nikivdev/code · error
failed to stash working tree: {}
Error message
failed to stash working tree: {} What it means
Thrown by stash_if_dirty (src/changes.rs:766) when `git stash push -u -m <msg>` exits non-zero while preparing a dirty working tree before unrolling a bundle. The message carries git's trimmed stderr, so it reflects the underlying git failure (not a Rust-side fault).
Source
Thrown at src/changes.rs:766
let (status, _ok) = git_output_in(repo_root, &["status", "--porcelain"])?;
if status.trim().is_empty() {
trace("working tree clean; no stash needed");
return Ok(None);
}
let message = format!(
"flow-diff-{}-{}",
&bundle_hash[..bundle_hash.len().min(8)],
Utc::now().format("%Y%m%d-%H%M%S")
);
let output = Command::new("git")
.current_dir(repo_root)
.args(["stash", "push", "-u", "-m", &message])
.output()
.context("failed to stash working tree")?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
bail!("failed to stash working tree: {}", stderr.trim());
}
let (stash_ref, _ok) = git_output_in(repo_root, &["stash", "list", "-1", "--pretty=%gd"])?;
let stash_ref = stash_ref.trim().to_string();
if stash_ref.is_empty() {
return Ok(Some(message));
}
record_stash(repo_root, &stash_ref, bundle_hash, &message)?;
Ok(Some(stash_ref))
}
View on GitHub (pinned to a747e741ae)
Solutions
- Read the stderr suffix in the message and fix the underlying git error it names (e.g. remove a stale .git/index.lock).
- Run `git stash push -u -m test` manually in the repo root to reproduce and see the full git error.
- Confirm repo_root is actually a git work tree (`git -C <root> rev-parse --is-inside-work-tree`).
- Commit or clean uncommitted changes manually, then retry the unroll so stashing is skipped.
- Check git version and hooks (gpg signing, smudge/clean filters) that could fail during stash.
Example fix
// before Error: failed to stash working tree: fatal: Unable to create '.../.git/index.lock': File exists. // after $ rm .git/index.lock $ f unroll <bundle> # stash succeeds
Defensive patterns
Strategy: try-catch
Validate before calling
// Shell: preconditions before running a stashing command
git -C "$REPO" rev-parse --is-inside-work-tree || exit 1
[ -f "$REPO/.git/index.lock" ] && { echo "stale index.lock"; exit 1; }
git -C "$REPO" status --porcelain | head -1 # ensure git itself is healthy Try / catch
if let Err(e) = unroll_bundle(repo_root, &bundle) {
if e.to_string().starts_with("failed to stash working tree") {
// surface git stderr; advise committing changes manually first
eprintln!("Fix git state per the error, or commit/stash manually and retry.");
} else { return Err(e); }
} Prevention
- Commit or stash changes manually before running bundle operations
- Watch for leftover .git/index.lock after crashes and remove it
- Keep git up to date and ensure no failing hooks/filters run on stash
When it happens
Trigger: unroll_bundle calls stash_if_dirty on a repo with uncommitted changes; the git stash subprocess fails — typically because repo_root is not a git work tree, git is missing/old, lock files exist (.git/index.lock), or untracked-file staging fails.
Common situations: Running the command inside a subdirectory project whose parent repo state is broken; concurrent git operations leaving an index.lock; corrupt .git after an interrupted process; custom gpg/signing hooks failing on stash; git not on PATH.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- git diff --cached --name-only failed
- Lin.app is not running
- codex skill-eval launchd install failed: {}
- git status failed with {}
- git add failed with {}
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/96ec74fef33d6812.
Report an issue: GitHub.