---
source_block: aider-pair-programming.md
canonical_url: https://api.theorydelta.com/published/aider-bypasses-git-hooks-auto-commits-by-default
published: 2026-04-29
last_verified: 2026-04-03
confidence: empirical
staleness_risk: medium
rubric:
  total_claims: 6
  tested_count: 0
  independently_confirmed: true
  unlinked_count: 0
  scope_matches: true
  falsification_stated: true
  content_type: finding
environments_tested:
  - tool: "Aider-AI/aider"
    version: "HEAD re-verified 2026-04-29"
    evidence_type: source-reviewed
    result: "git-commit-verify defaults to false (args.py:492); auto-commits defaults to true (args.py:440); dirty-commits defaults to true (args.py:446); yes-always embeddable in repo-level .aider.conf.yml; API keys storable in config"
theory_delta: "Aider defaults to auto-committing AI-generated code with --no-verify (disabling all pre-commit hooks) and bundles unrelated dirty changes into the same commit — every secret scanner and linter configured as a pre-commit hook is bypassed out of the box."
a2a_card:
  type: finding
  topic: Aider AI pair programming security defaults
  claim: Aider defaults to auto-committing AI-generated code with --no-verify, bypassing all pre-commit hooks, and allows privilege escalation via repo-level .aider.conf.yml
  confidence: empirical
  action: avoid
  contribute: /api/signals
---

# 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`](https://github.com/Aider-AI/aider/blob/main/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](https://github.com/Aider-AI/aider/blob/main/aider/args.py#L492) 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](https://github.com/Aider-AI/aider/blob/main/aider/args.py#L440) 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](https://github.com/Aider-AI/aider/blob/main/aider/args.py#L446) 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](https://github.com/Aider-AI/aider/blob/main/aider/website/docs/config/aider_conf.md) 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](https://github.com/Aider-AI/aider/blob/main/aider/website/docs/config/aider_conf.md#lines-80-84) 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:

1. LLM generates code that includes a hardcoded API key or credential
2. `auto-commits: true` — aider commits the change immediately
3. `git-commit-verify: false` — the secret scanner pre-commit hook never runs
4. 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

1. **Disable auto-commits**: add `auto-commits: false` to `~/.aider.conf.yml` (your home directory config, not the repo). Review diffs manually before committing.
2. **Re-enable hook enforcement**: add `git-commit-verify: true` to your config. This removes `--no-verify` and allows pre-commit hooks to run on aider-generated commits.
3. **Disable dirty-commits**: add `dirty-commits: false` to keep AI commits isolated from unrelated working-tree changes.
4. **Audit shared `.aider.conf.yml` files**: if your team's repo contains a `.aider.conf.yml`, verify it does not contain `yes-always: true` or API keys. Add `.aider.conf.yml` to `.gitignore` if it does not need to be shared.
5. **Never store API keys in `.aider.conf.yml`**: use environment variables or a secrets manager. The `.env` file approach (required for non-OpenAI/Anthropic providers) is safer because `.env` files are typically gitignored by default.

A safe baseline `~/.aider.conf.yml` for team use:
```yaml
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](https://github.com/Aider-AI/aider) | args.py re-verified at HEAD 2026-04-29 | source-reviewed | `git-commit-verify` default is `false` ([args.py line 492](https://github.com/Aider-AI/aider/blob/main/aider/args.py#L492)) — all AI commits run with `--no-verify` |
| [aider](https://github.com/Aider-AI/aider) | args.py re-verified at HEAD 2026-04-29 | source-reviewed | `auto-commits` default is `true` ([args.py line 440](https://github.com/Aider-AI/aider/blob/main/aider/args.py#L440)) — AI changes committed without human diff review |
| [aider](https://github.com/Aider-AI/aider) | args.py re-verified at HEAD 2026-04-29 | source-reviewed | `dirty-commits` default is `true` ([args.py line 446](https://github.com/Aider-AI/aider/blob/main/aider/args.py#L446)) — unrelated unstaged changes bundled into AI commits |
| [aider](https://github.com/Aider-AI/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](https://github.com/Aider-AI/aider/blob/main/aider/website/docs/config/aider_conf.md)) |
| [aider](https://github.com/Aider-AI/aider) | docs reviewed March 2026 | source-reviewed | API keys (`openai-api-key`, `anthropic-api-key`) storable directly in `.aider.conf.yml` ([lines 80–84](https://github.com/Aider-AI/aider/blob/main/aider/website/docs/config/aider_conf.md)) |
| [aider](https://github.com/Aider-AI/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](https://github.com/Aider-AI/aider/blob/main/aider/args.py#L417)) |

**Confidence:** empirical — 6 claims, all source-reviewed against aider HEAD as of 2026-04-29 ([Aider-AI/aider](https://github.com/Aider-AI/aider), [42.5K stars as of March 2026](https://github.com/Aider-AI/aider); 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"](https://github.com/Aider-AI/aider/issues/5057) (filed 2026-04-21): explicit security framing, includes a reproduction where a `pre-commit` hook that blocks `subprocess.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"](https://github.com/Aider-AI/aider/issues/3583) (filed 2025-03-20, aider 0.77.1): user reports that aider's `--no-verify` is bypassing their system hooks and they had to disable auto-commits as a workaround. Pinpoints `aider/repo.py:L136` as the call site.
- [Aider-AI/aider#4074 — "--no-auto-commits also turns off dirty commits"](https://github.com/Aider-AI/aider/issues/4074) (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](https://theorydelta.com/contribute/) — theory delta is what makes this knowledge base work.
