Before submitting
Summary
check-yaml (from pre-commit/pre-commit-hooks) passes under prek but fails under pre-commit for the same config and the same file, because prek's fast path runs a bundled builtin implementation instead of the pinned hook, and that builtin accepts YAML tags like !reference that the real hook rejects unless --unsafe is set.
MRE:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-yaml
# test.yaml
foo: !reference [.bar, script]
$ git init
...
$ ls -a
. .. .git .pre-commit-config.yaml test.yaml
$ uvx prek run -a
yaml...............................................................Passed
$ uvx pre-commit run -a
yaml...............................................................Failed
- exit code: 1 could not determine a constructor for the tag '!reference' in
"test.yaml", line 1, column 6
$ PREK_NO_FAST_PATH=1 uvx prek run -a
yaml...............................................................Failed
- exit code: 1 could not determine a constructor for the tag '!reference' in
"test.yaml", line 1, column 6
$ uvx pre-commit --version
pre-commit 4.6.2
$ uvx prek --version
prek 0.4.14
No --unsafe is set in the hook args, so check-yaml should reject the unknown tag, same as pre-commit. PREK_NO_FAST_PATH=1 makes prek behave the same as pre-commit exactly, so I assume the fast path builtin is the cause.
In practice, we have two problems now:
- Fast path is on by default and there's no per-hook/per-repo way to turn it off in
.pre-commit-config.yaml, so we need to use a global PREK_NO_FAST_PATH env var which. Setting that just for local dev while CI stays on defaults defeats the point of matching CI and local behavior in a corporate setup.
- Even at
-vvv, the log only says Running hook check-yaml in "fast path", but the average reader or those confronted first time with it, don't know what's happening there. It especially doesn't state that a different (bundled) implementation is being used in place of the pinned one, or that its defaults differ, which makes this divergence very hard to diagnose ans questionable why the hook-repository is installed at all.
Platform
Linux 6.17.0-1032-oem x86_64 GNU/Linux
Version (current: 0.4.14)
0.4.14
.pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-yaml
Log file
❯ uvx prek -vvv run -a
2026-08-25T10:14:03.626154Z DEBUG prek: 0.4.14
2026-08-25T10:14:03.626200Z DEBUG Args: ["prek", "-vvv", "run", "-a"]
2026-08-25T10:14:03.628043Z TRACE root: close time.busy=1.80ms time.idle=2.11µs
2026-08-25T10:14:03.628084Z DEBUG Git root: /home/bts/del
2026-08-25T10:14:03.628135Z DEBUG Found workspace root at `/home/bts/del`
2026-08-25T10:14:03.628146Z TRACE Include selectors: ``
2026-08-25T10:14:03.628157Z TRACE Skip selectors: ``
2026-08-25T10:14:03.628246Z DEBUG discover{root="/home/bts/del" config=None refresh=false}: Loaded workspace from cache
2026-08-25T10:14:03.628276Z DEBUG discover{root="/home/bts/del" config=None refresh=false}: Loading project configuration path=.pre-commit-config.yaml
2026-08-25T10:14:03.628492Z TRACE discover{root="/home/bts/del" config=None refresh=false}: close time.busy=303µs time.idle=722ns
2026-08-25T10:14:03.628746Z TRACE Checking lock resource="store" path=/home/bts/.cache/prek/.lock
2026-08-25T10:14:03.628770Z DEBUG Acquired lock resource="store"
2026-08-25T10:14:03.631441Z TRACE No requires-python found in pyproject.toml hook=check-yaml
2026-08-25T10:14:03.631504Z TRACE Released lock path=/home/bts/.cache/prek/.lock
2026-08-25T10:14:03.631522Z DEBUG Hooks going to run: ["check-yaml"]
2026-08-25T10:14:03.631550Z TRACE ls_files{cwd="/home/bts/del"}: Executing `cd /home/bts/del && /usr/bin/git -c core.useBuiltinFSMonitor=false --literal-pathspecs ls-files -z -- /home/bts/del`
2026-08-25T10:14:03.633477Z TRACE ls_files{cwd="/home/bts/del"}: close time.busy=343µs time.idle=1.59ms
2026-08-25T10:14:03.633510Z DEBUG All files in the workspace: 2
2026-08-25T10:14:03.634468Z TRACE Checking lock resource="store" path=/home/bts/.cache/prek/.lock
2026-08-25T10:14:03.634498Z DEBUG Acquired lock resource="store"
2026-08-25T10:14:03.636652Z TRACE Executing `/home/bts/.local/share/uv/python/cpython-3.14.3-linux-x86_64-gnu/bin/python3.14 -I -c import sys, json
info = {
"version": ".".join(map(str, sys.version_info[:3])),
"base_exec_prefix": sys.base_exec_prefix,
}
print(json.dumps(info))
`
2026-08-25T10:14:03.663545Z TRACE Released lock path=/home/bts/.cache/prek/.lock
2026-08-25T10:14:03.664159Z TRACE Files for project `.` after filtered: 2
2026-08-25T10:14:03.664183Z DEBUG Running priority group with priority 0: ["check-yaml"]
2026-08-25T10:14:03.664213Z TRACE matching_filenames{hook="check-yaml"}: close time.busy=8.69µs time.idle=1.97µs
2026-08-25T10:14:03.664240Z TRACE Files for hook `check-yaml` after filtering matched=true filenames=2
2026-08-25T10:14:03.664270Z DEBUG run{hook_id=check-yaml language=python}: Running hook `check-yaml` in fast path
2026-08-25T10:14:03.664504Z INFO run{hook_id=check-yaml language=python}: close time.busy=201µs time.idle=44.9µs
check yaml...............................................................Passed
- hook id: check-yaml
- description: checks yaml files for parseable syntax
- duration: 0.00s
Before submitting
Summary
check-yaml (from pre-commit/pre-commit-hooks) passes under prek but fails under pre-commit for the same config and the same file, because prek's fast path runs a bundled builtin implementation instead of the pinned hook, and that builtin accepts YAML tags like
!referencethat the real hook rejects unless--unsafeis set.MRE:
No
--unsafeis set in the hook args, so check-yaml should reject the unknown tag, same as pre-commit.PREK_NO_FAST_PATH=1makes prek behave the same as pre-commit exactly, so I assume the fast path builtin is the cause.In practice, we have two problems now:
.pre-commit-config.yaml, so we need to use a globalPREK_NO_FAST_PATHenv var which. Setting that just for local dev while CI stays on defaults defeats the point of matching CI and local behavior in a corporate setup.-vvv, the log only says Running hook check-yaml in "fast path", but the average reader or those confronted first time with it, don't know what's happening there. It especially doesn't state that a different (bundled) implementation is being used in place of the pinned one, or that its defaults differ, which makes this divergence very hard to diagnose ans questionable why the hook-repository is installed at all.Platform
Linux 6.17.0-1032-oem x86_64 GNU/Linux
Version (current: 0.4.14)
0.4.14
.pre-commit-config.yaml
Log file