[BUG] `gitStatus` snapshot is captured at process launch, not at first-prompt-submit — goes stale when other workers commit before you type

Resolved 💬 4 comments Opened May 27, 2026 by KamilDev Closed Jul 14, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [ ] I am using the latest version of Claude Code — I'm on 2.1.140, held back due to an unrelated rendering regression in newer versions. I checked the CHANGELOG.md on main for fixes to the stale-gitStatus snapshot and found nothing relevant, so this bug should still apply to the latest version.

Related

#24487 reported the same root cause with a "session resumed days later" repro and was auto-closed NOT_PLANNED by stale-bot for inactivity, then auto-locked. The closing comment instructs filing a new issue if still relevant — this is that new issue, with a different (and much more common) repro path that doesn't require resuming an old session.

What's Wrong?

The gitStatus block in the system prompt is snapshotted at process launch, not at the moment the user submits their first prompt. Anything that lands in the working tree between launch and first message is invisible to the snapshot — so the agent's "initial" mental model of the repo is already wrong on turn one.

This is routine, not edge-case. The standard trigger is multiple Claude Code tabs: tab A is working on a refactor. User opens tab B, starts drafting a prompt in the input box. Tab A finishes and commits. User submits the prompt to tab B. Tab B's snapshot still shows tab A's pre-commit dirty state — even though by the time the model sees the user's first message, the tree is already clean.

Steps to Reproduce

  1. git init a repo with a clean tree.
  2. Launch Claude Code (do not submit a prompt yet).
  3. In another terminal: echo x >> file.txt && git add file.txt && git commit -m "x".
  4. Now submit any prompt to the Claude Code session from step 2 (e.g. "what does git status say?").
  5. Observe: the system-prompt gitStatus block shows the pre-step-3 state (file.txt untracked or whatever it was at launch), but live git status reports a clean tree.

Expected Behavior

gitStatus reflects the state of the working tree at the moment the user actually submits a prompt — or carries a timestamp the model can use to invalidate it.

Actual Behavior

gitStatus reflects state captured at process launch. The model treats this as authoritative and:

  • Reports modified files that aren't modified.
  • Narrates a reconciliation story to explain the discrepancy when live git status disagrees (e.g. "the file must have been committed outside this conversation"). This confuses the user, who knows nothing happened "outside this conversation" — the snapshot was simply wrong from turn one.

Concrete Evidence From a Real Session

Observed timeline:

  • T+0 — Session A launched. System-prompt gitStatus snapshot captured at this moment: HEAD = commit X, file F listed as modified.
  • T+5min — Session B (a different Claude Code tab in the same repo) committed file F. New HEAD = commit Y.
  • T+~6min — First user message submitted to session A. Real HEAD is now Y; working tree is clean. Session A's system prompt still shows the T+0 snapshot (HEAD = X, F modified).
  • Later in session A: model ran live git status, got "working tree clean," noticed it contradicted the snapshot, and told the user "the file modification must have been committed outside this conversation" — narrating a reconciliation story instead of recognizing the snapshot was simply stale.

The gap between snapshot capture and first prompt was ~5 minutes — entirely normal for "open a tab, draft a prompt, hit enter."

Distinct From #24487

#24487 framed this as a problem for resumed sessions and large refactor commits. This report adds:

  • Common trigger path: concurrent Claude Code tabs, which is the standard recommended workflow for parallel work — not an edge case.
  • Model-behavior failure mode: when live state disagrees with the snapshot, the model fabricates a reconciliation narrative ("must have been committed outside this conversation") instead of recognizing the snapshot is stale. The system prompt frames gitStatus as authoritative initial context, so the model defends it. Even users with CLAUDE.md rules saying "ignore the snapshot, trust live state" still get this failure mode because the model only consults live state when the snapshot is contradicted, by which point it's already in defend-the-snapshot mode.

Proposed Fix

Any of these would resolve it:

  1. Snapshot at first-prompt-submit, not at process launch. The simplest and most correct fix.
  2. Re-snapshot whenever the input box has been idle for > N seconds before submit. Cheap upper-bound on staleness.
  3. Timestamp the snapshot so the model can compare against current time and decide to re-run git status if it's old.
  4. Index-based invalidation: if .git/index mtime is newer than the snapshot, omit the block or flag it stale.

Additionally, the system prompt's framing of gitStatus as "this is the git status at the start of the conversation" trains the model to treat it as ground truth. Even a small wording change — "this may be stale; verify with git status before relying on it" — would help mitigate the model-behavior half of the bug.

Environment

  • Claude Code version: 2.1.140
  • Model: Opus 4.7
  • OS: Windows 11
  • Shell: PowerShell 7, running in the VS Code integrated terminal

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗