{"record":{"id":"9ef70d453cc78f5e","repo":"GitoxideLabs/gitoxide","slug":"changes-can-only-be-stashed-at-the-current-head","errorCode":null,"errorMessage":"changes can only be stashed at the current HEAD","messagePattern":"changes can only be stashed at the current HEAD","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/stash.rs","lineNumber":130,"sourceCode":"}\n\nfn delete_edit(name: gix::refs::FullName, target: Target) -> RefEdit {\n    RefEdit::delete(name, PreviousValue::MustExistAndMatch(target))\n}\n\n#[tracing::instrument(skip_all, fields(commit_id = %id))]\npub(crate) fn save_manual(repository_path: &Path, bare: bool, id: ObjectId) -> Result<String> {\n    let repo = open_repository(repository_path, bare, false).context(\"could not open repository to stash changes\")?;\n    let workdir = repo\n        .workdir()\n        .context(\"stashing changes requires a worktree\")?\n        .to_owned();\n    let head = repo\n        .head_id()\n        .context(\"stashing changes requires a born HEAD\")?\n        .detach();\n    if head != id {\n        anyhow::bail!(\"changes can only be stashed at the current HEAD\");\n    }\n    if repo\n        .index_or_empty()\n        .context(\"could not inspect the index before stashing\")?\n        .entries()\n        .iter()\n        .any(|entry| entry.stage() != gix::index::entry::Stage::Unconflicted)\n    {\n        anyhow::bail!(\"cannot stash changes with unresolved index conflicts\");\n    }\n    let name = reference(id)?;\n    if repo.try_find_reference(name.as_ref())?.is_some() {\n        anyhow::bail!(\"{} already has saved worktree state\", id.to_hex_with_len(7));\n    }\n    drop(repo);\n    if !super::review::is_dirty(&workdir)? {\n        anyhow::bail!(\"there are no worktree or index changes to stash\");\n    }","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/stash.rs#L112-L148","documentation":"Manual stash saving keys the saved worktree state by the current HEAD commit ID. This error fires when the caller supplied a commit ID that does not equal the repository's current HEAD id, so tix cannot attribute the state to HEAD. It guards against stashing changes that belong to a different, unborn, or non-checked-out commit.","triggerScenarios":"Calling `stash::save_manual` with an `id` argument different from `repo.head_id()` — e.g. after HEAD moved (checkout/rebase) between obtaining the id and saving, or passing an arbitrary commit id.","commonSituations":"Scripting stashes while HEAD changes concurrently; passing a target commit id from a UI that is not the checked-out HEAD; detached HEAD transitions mid-operation.","solutions":["Pass the commit id obtained from the repository's current `head_id()` at the time of the call","Re-checkout or reset HEAD so it matches the id you intend to stash at","Re-read HEAD and retry the save atomically if HEAD may have moved"],"exampleFix":"// before\nlet target = old_commit_id;\nstash::save_manual(path, bare, workdir, target)?;\n// after\nlet repo = gix::open(path)?;\nlet target = repo.head_id().expect(\"born HEAD\").detach();\nstash::save_manual(path, bare, workdir, target)?;","handlingStrategy":"validation","validationCode":"let repo = gix::open(path)?;\nlet head = repo.head_id().context(\"born HEAD required\")?.detach();\nif head != id {\n    anyhow::bail!(\"re-read HEAD; the id to stash must equal the current HEAD\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always obtain the id to stash from `repo.head_id()` immediately before the call","Re-open or refresh the repository handle if other processes may have moved HEAD","Never pass historical commit IDs to save_manual"],"tags":["git","head","precondition","stash"],"backgroundTag":"invalid-state-transition","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}