{"record":{"id":"96ec74fef33d6812","repo":"nikivdev/code","slug":"failed-to-stash-working-tree","errorCode":null,"errorMessage":"failed to stash working tree: {}","messagePattern":"failed to stash working tree: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/changes.rs","lineNumber":766,"sourceCode":"    let (status, _ok) = git_output_in(repo_root, &[\"status\", \"--porcelain\"])?;\n    if status.trim().is_empty() {\n        trace(\"working tree clean; no stash needed\");\n        return Ok(None);\n    }\n\n    let message = format!(\n        \"flow-diff-{}-{}\",\n        &bundle_hash[..bundle_hash.len().min(8)],\n        Utc::now().format(\"%Y%m%d-%H%M%S\")\n    );\n    let output = Command::new(\"git\")\n        .current_dir(repo_root)\n        .args([\"stash\", \"push\", \"-u\", \"-m\", &message])\n        .output()\n        .context(\"failed to stash working tree\")?;\n    if !output.status.success() {\n        let stderr = String::from_utf8_lossy(&output.stderr);\n        bail!(\"failed to stash working tree: {}\", stderr.trim());\n    }\n\n    let (stash_ref, _ok) = git_output_in(repo_root, &[\"stash\", \"list\", \"-1\", \"--pretty=%gd\"])?;\n    let stash_ref = stash_ref.trim().to_string();\n    if stash_ref.is_empty() {\n        return Ok(Some(message));\n    }\n\n    record_stash(repo_root, &stash_ref, bundle_hash, &message)?;\n    Ok(Some(stash_ref))\n}\n","sourceCodeStart":748,"sourceCodeEnd":778,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/changes.rs#L748-L778","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nError: failed to stash working tree: fatal: Unable to create '.../.git/index.lock': File exists.\n// after\n$ rm .git/index.lock\n$ f unroll <bundle>  # stash succeeds","handlingStrategy":"try-catch","validationCode":"// Shell: preconditions before running a stashing command\ngit -C \"$REPO\" rev-parse --is-inside-work-tree || exit 1\n[ -f \"$REPO/.git/index.lock\" ] && { echo \"stale index.lock\"; exit 1; }\ngit -C \"$REPO\" status --porcelain | head -1  # ensure git itself is healthy","typeGuard":null,"tryCatchPattern":"if let Err(e) = unroll_bundle(repo_root, &bundle) {\n    if e.to_string().starts_with(\"failed to stash working tree\") {\n        // surface git stderr; advise committing changes manually first\n        eprintln!(\"Fix git state per the error, or commit/stash manually and retry.\");\n    } else { return Err(e); }\n}","preventionTips":["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"],"tags":["git","stash","subprocess","rust"],"backgroundTag":"git-command-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}