--- topic: troubleshooting source_keys: - context7-pre-commit-com - pre-commit-com --- ## Common issues ### Hooks don't run on `git commit` `pre-commit install` was never run in this clone. Run it. Git hooks are per-clone — they are not committed. ### Hook modified files but commit was blocked Expected behavior. The hook fixed files, so the staged version is now stale. Re-stage the modified files and commit again. ```bash git add -u git commit -m "same message" ``` ### `SKIP` not working The value must be the exact `id` field from the hook definition. Comma-separated, no spaces. ```bash SKIP=check-yaml,trailing-whitespace git commit -m "msg" # correct SKIP=check-yaml, trailing-whitespace git commit -m "msg" # wrong — space after comma ``` ### Hook runs but matches wrong files (or no files) `files:` uses `re.search()`, not a full-string match. `\.py$` matches any path ending in `.py`. To match only repo root: `^[^/]+\.py$`. Use `identify-cli ` to see exactly what type tags a file has, then verify your `types:` filter. ### Hook environment is stale or broken ```bash pre-commit clean # wipe all environments pre-commit install-hooks # rebuild everything ``` Or clean just a specific repo: ```bash pre-commit gc # remove only unused environments ``` ### `rev` is a branch name — `autoupdate` broke it Branch refs are mutable; pre-commit resolves them at install time and then they drift. Always use a tag or commit SHA. Fix: ```bash pre-commit autoupdate # finds the latest tag and rewrites rev in place ``` ### `validate-config` returns an error Schema violation in the YAML. Common causes: - Missing `id` under a hook block - Missing `rev` under a non-local repo block - `repo: local` hook missing required `language` or `entry` fields - Indentation error (YAML parsed but pre-commit schema rejected it) ### `check-hooks-apply` fails A hook's `files`/`types` filter matches zero files in the repo. Either broaden the filter or remove the hook. This is a sign the hook is dead weight. ### `check-useless-excludes` fails An `exclude` pattern matches no files. Remove or fix it. ### SSH cloning fails in CI Export `SSH_AUTH_SOCK` in the CI environment, or use HTTPS URLs for hook repos. ### HTTP proxy needed ```bash export http_proxy=http://proxy.example.com:3128 export https_proxy=http://proxy.example.com:3128 export no_proxy=localhost,127.0.0.1 ``` ### Hook too slow in CI - Check `require_serial: false` (default) — hooks run in parallel by default - Cache `$PRE_COMMIT_HOME` keyed on the hash of `.pre-commit-config.yaml` - Use `--from-ref`/`--to-ref` instead of `--all-files` to only check changed files ### `language: system` deprecated warning Renamed to `language: unsupported`. Old name still works as an alias but triggers a deprecation warning on newer versions. ### `pre-commit install -f` wiped my existing hooks `-f` overwrites `.git/hooks/pre-commit` unconditionally. Without `-f`, pre-commit migrates the existing hook so both run. Only use `-f` deliberately. ### `pretty-format-json` fails but doesn't fix `pretty-format-json` only fixes in-place when `args: [--autofix]` is passed. Without it, the hook just fails. Add `--autofix` to have it modify the file (the commit will then be blocked until you re-stage). ## Skill/agent-specific gotchas - Always call `pre-commit validate-config` after writing or modifying config — do not assume valid YAML is valid pre-commit schema. - `pre-commit autoupdate` modifies the config file in-place. If a skill calls it, re-read the file to get updated `rev` values for display/logging. - Local hooks with `language: unsupported_script` require the `entry` script to be executable. If the skill creates the script, `chmod +x` it. - The `stages` key in a hook override must match what was set in `default_install_hook_types` (or the `-t` flags passed to `pre-commit install`), otherwise the hook will never run. - `always_run: true` combined with `pass_filenames: false` is the correct pattern for repo-wide validators (test suites, manifest checks) that do not operate on individual files.