Aider bypasses git pre-commit hooks and auto-commits AI-generated code by default
Aider bypasses git pre-commit hooks and auto-commits AI-generated code by default
What you expect
Aider, as a tool designed for collaborative coding, would follow standard git workflow conventions: pre-commit hooks run on every commit, including AI-generated ones, and the user reviews changes before they are committed. The documentation presents .aider.conf.yml as a convenience for per-project configuration.
What actually happens
The source code at aider/args.py establishes three security-hostile defaults that combine into a single exposure pipeline:
Default 1: git-commit-verify: false — pre-commit hooks bypassed
args.py line 492 sets git-commit-verify to false by default. This means aider runs git commit with the --no-verify flag on every AI-generated commit. Secret scanners, linters, formatters, and test runners configured as pre-commit hooks do not execute. The mechanism for bypassing hooks is not a bug or edge case — it is the configured default.
Default 2: auto-commits: true — no human diff review
args.py line 440 sets auto-commits to true by default. Every file change produced by the LLM is committed immediately without presenting a diff for human review. Combined with git-commit-verify: false, AI-generated code containing secrets or regressions is committed before any hook-based detection could run.
Default 3: dirty-commits: true — unrelated changes bundled in
args.py line 446 sets dirty-commits to true by default. Unstaged changes present in the working tree at the time aider runs are bundled into the AI commit. This destroys clean audit trails: a single aider commit may contain both the AI’s changes and unrelated human edits, making it impossible to attribute changes accurately in a post-incident review.
Repo-level config as a privilege escalation vector
The aider configuration docs show that yes-always: true can be written to .aider.conf.yml. Aider loads this file from the repo root, the user’s home directory, or the current working directory. A committed .aider.conf.yml with yes-always: true silently removes all confirmation prompts for every developer who runs aider in that directory — with no warning, no audit trail, and no indicator that the setting originated from a repo-level file rather than the user’s own configuration.
API keys storable in .aider.conf.yml
The same configuration docs present storing openai-api-key and anthropic-api-key directly in .aider.conf.yml as a supported workflow (lines 80–84). If that file is committed to version control — or if it ends up in git history — credentials are exposed to anyone with repo access.
The triple exposure in sequence
The combination of these defaults creates a single end-to-end exposure path:
- LLM generates code that includes a hardcoded API key or credential
auto-commits: true— aider commits the change immediatelygit-commit-verify: false— the secret scanner pre-commit hook never runs- The commit lands in git history before any human or automated check can intervene
What this means for you
If you use aider with its defaults, any secret the LLM accidentally includes in generated code bypasses the exact tooling (pre-commit hooks, secret scanners) teams install to prevent credential leaks. This is not a failure of the scanner — the scanner never runs because aider disables it by default.
If your team shares a repo, a contributor can commit a .aider.conf.yml with yes-always: true. Every developer who runs aider in that repo inherits fully autonomous, no-confirmation behavior without knowing it came from a repo-level config. This is equivalent to Claude Code’s --dangerouslySkipPermissions flag, but it is silent, version-controlled, and inherited by all collaborators.
If you store API keys in .aider.conf.yml following the documented approach, those keys are one accidental commit away from being in version control — and git history is not easy to sanitize after the fact.
Pre-commit hook pipelines (trufflehog, gitleaks, detect-secrets, eslint, black) are systematically bypassed by aider’s defaults. The tier-3 hook-based enforcement that teams deploy specifically to catch AI-generated issues does not execute on aider commits unless explicitly re-enabled.
What to do
- Disable auto-commits: add
auto-commits: falseto~/.aider.conf.yml(your home directory config, not the repo). Review diffs manually before committing. - Re-enable hook enforcement: add
git-commit-verify: trueto your config. This removes--no-verifyand allows pre-commit hooks to run on aider-generated commits. - Disable dirty-commits: add
dirty-commits: falseto keep AI commits isolated from unrelated working-tree changes. - Audit shared
.aider.conf.ymlfiles: if your team’s repo contains a.aider.conf.yml, verify it does not containyes-always: trueor API keys. Add.aider.conf.ymlto.gitignoreif it does not need to be shared. - Never store API keys in
.aider.conf.yml: use environment variables or a secrets manager. The.envfile approach (required for non-OpenAI/Anthropic providers) is safer because.envfiles are typically gitignored by default.
A safe baseline ~/.aider.conf.yml for team use:
auto-commits: false
git-commit-verify: true
dirty-commits: false
Falsification criterion: This finding would be disproved by aider releasing a version where git-commit-verify defaults to true in args.py, or where auto-commits defaults to false — either change would eliminate the bypass for new installations. It would also be partially falsified by a warning emitted at startup when both auto-commits: true and git-commit-verify: false are active simultaneously.
Evidence
| Tool | Version | Evidence | Result |
|---|---|---|---|
| aider | args.py re-verified at HEAD 2026-04-29 | source-reviewed | git-commit-verify default is false (args.py line 492) — all AI commits run with --no-verify |
| aider | args.py re-verified at HEAD 2026-04-29 | source-reviewed | auto-commits default is true (args.py line 440) — AI changes committed without human diff review |
| aider | args.py re-verified at HEAD 2026-04-29 | source-reviewed | dirty-commits default is true (args.py line 446) — unrelated unstaged changes bundled into AI commits |
| aider | docs reviewed March 2026 | source-reviewed | yes-always: true embeddable in repo-level .aider.conf.yml — inherited silently by all users (aider_conf.md) |
| aider | docs reviewed March 2026 | source-reviewed | API keys (openai-api-key, anthropic-api-key) storable directly in .aider.conf.yml (lines 80–84) |
| aider | args.py re-verified at HEAD 2026-04-29 | source-reviewed | add-gitignore-files off by default, but when enabled sends .env/secrets to LLM context window (args.py line 417) |
Confidence: empirical — 6 claims, all source-reviewed against aider HEAD as of 2026-04-29 (Aider-AI/aider, 42.5K stars as of March 2026; the older paul-gauthier/aider URL now 301-redirects to Aider-AI/aider). No independent CVE or GHSA exists for these defaults; evidence is from aider’s own source code, documentation, and third-party user reports filed against the project (see Independent reports below).
Independent reports
These third-party issues were filed against the upstream repo by users (not maintainers) reporting the same exposure independently:
- Aider-AI/aider#5057 — “Default runtime commits bypass pre-commit hooks via —no-verify” (filed 2026-04-21): explicit security framing, includes a reproduction where a
pre-commithook that blockssubprocess.check_output("...", shell=True)is bypassed by an aider commit but enforced for a manual commit. Confirms defaults 1 and 2. - Aider-AI/aider#3583 — “Aider using no-verify by default for commits” (filed 2025-03-20, aider 0.77.1): user reports that aider’s
--no-verifyis bypassing their system hooks and they had to disable auto-commits as a workaround. Pinpointsaider/repo.py:L136as the call site. - Aider-AI/aider#4074 — “—no-auto-commits also turns off dirty commits” (filed 2025-06-11): independent corroboration of the auto-commits / dirty-commits behavior coupling.
Strongest case against: These defaults exist because aider is optimized for solo developer productivity: auto-commits provide a clean undo history, and --no-verify avoids breaking aider’s flow when hooks are slow or fail on generated code. A developer who owns their entire pre-commit pipeline and trusts their LLM may prefer these defaults. The finding’s severity depends on team context — the exposure is highest in shared repos with pre-commit secret scanning that teams assume is running.
Open questions: Does aider emit any runtime warning when auto-commits: true and git-commit-verify: false are both active? Does aider ever validate that a loaded .aider.conf.yml originated from a user home directory vs a repo root, and if so does it warn? Has any team been affected by leaked credentials via auto-committed AI code?
Seen different? Contribute your evidence — theory delta is what makes this knowledge base work.