Skip to content
Documentation GitHub
Workflow Issues

lint-staged Pre-Commit Failure Drops Previously Staged Files

Historical: lint-staged was removed on 2026-03-01. Kept for reference.


title: lint-staged Pre-Commit Failure Drops Previously Staged Files category: workflow-issues created: 2026-02-20 symptoms:

  • Commit succeeds but contains fewer files than expected
  • ‘“git add” files disappear from staging after a pre-commit hook failure and retry’
  • Partial commits despite staging all files before committing tags:
  • lint-staged
  • pre-commit
  • git
  • partial-commit
  • agent-team related:
  • docs/solutions/workflow-issues/agent-team-orchestration-at-scale.md
  • docs/solutions/workflow-issues/batched-commits-anti-pattern.md

Historical (2026-03-01): lint-staged was removed from the pre-commit hook. The pre-commit hook now runs gitleaks only. This document is kept for reference — the described problem no longer applies. See .husky/pre-commit and tools/precheck.sh --fix.

lint-staged Pre-Commit Failure Drops Previously Staged Files

Problem

When git commit triggers lint-staged and a linter fails (e.g., clippy error), the commit is aborted — but previously staged files are silently unstaged. A subsequent fix-and-retry commits only the files that were re-staged, not the full original set.

Symptoms:

  • git add 16 files → git commit → clippy fails → fix clippy error → git add the fixed file → git commitonly 3 files in the commit (the rest vanished from staging)
  • No error message indicates files were dropped
  • git status after the failed commit shows previously staged files as “modified” (unstaged)

Investigation

Steps Tried

  1. Staged all ~16 files with git add → verified with git status showing all staged
  2. Ran git commit → lint-staged triggered → clippy found unnecessary_map_or → commit aborted
  3. Fixed the clippy error in-place
  4. Staged only the fixed file → ran git commit again → commit succeeded
  5. Discovered: commit only contained 3 files, not the original 16

Root Cause

lint-staged uses a stash-based isolation strategy:

  1. Before running linters: git stash saves unstaged changes (including the working tree state)
  2. Runs linters against only the staged files
  3. If linters fail: restores the stash to “revert to original state”

The restore operation (git stash pop) replaces the entire index, effectively unstaging all previously staged files. The working directory retains the modifications, but the staging area is reset.

This is by design — lint-staged wants to guarantee that a failed commit leaves the repository in the exact state it was in before the commit attempt. But the side effect is that your carefully staged files are all unstaged.

Timeline:
git add file1..file16 # 16 files staged
git commit # triggers lint-staged
├─ lint-staged: git stash # saves unstaged state
├─ lint-staged: run clippy # FAILS
└─ lint-staged: git stash pop # restores pre-commit state
# → ALL 16 files now UNSTAGED
git add fixedFile # only 1 file staged
git commit # succeeds with 1-3 files

Solution

After any lint-staged failure, re-stage ALL intended files before retrying the commit.

Workflow

Terminal window
# After a pre-commit hook failure:
git status # Check — files are now unstaged
git add file1 file2 ... fileN # Re-stage everything (not just the fix)
git commit -m "..." # Retry with full staging

For Agent Teams (Leader-Commits Pattern)

When the leader is committing on behalf of multiple agents:

Terminal window
# Collect all agent files into a list BEFORE the first commit attempt
FILES="path/to/file1 path/to/file2 ..."
# After any failure, always re-add the full list
git add $FILES
git commit -m "..."

Implementation Notes

  • Always check git status after a failed commit — verify your staging area matches expectations
  • The fix itself may need staging too — if you edited a file to fix a linter error, that file needs to be staged alongside the re-staged originals
  • This compounds with multiple failures — each failure cycle drops staging again

Prevention

Best Practices

  • After any pre-commit failure, run git status before retrying
  • Keep a list of intended files when committing large changesets
  • Consider running linters manually before commit (cargo clippy, pnpm lint) to catch errors before lint-staged gets involved
  • In agent team workflows, the leader should maintain the full file list and re-stage everything on retry

Warning Signs

  • Commit message says “wave 1 + wave 2” but git show --stat only shows 3 files
  • Post-commit git status shows unexpected modified files
  • A second commit is needed to “catch” the remaining files

This interacts with two other documented lint-staged behaviors:

  1. lint-staged gotcha (directory renames): Renaming directories exposes pre-existing lint errors in newly-matched files → fix as part of the rename commit
  2. lint-staged partial staging: When files are both renamed (staged) AND modified (unstaged), lint-staged stashes unstaged changes → stage both rename and modifications together

All three patterns stem from lint-staged’s stash-based isolation strategy.

References

Was this page helpful?