GitoxideLabs/gitoxide · warning
there are no worktree or index changes to stash
Error message
there are no worktree or index changes to stash
What it means
Stashing only makes sense when there is something to save. `save_manual` checks the worktree dirtiness via `super::review::is_dirty` and bails when neither the index nor the worktree differs from HEAD, so an empty stash is never created. This mirrors `git stash`'s "No local changes to save" behavior but as a hard error.
Solutions
- Verify there are local changes (`git status`) before stashing
- Make the intended edits or stage changes, then stash
- Treat a clean worktree as a no-op in scripts: skip the stash call when `is_dirty` is false
Example fix
// before unconditional stash
stash::save_manual(path, bare, workdir, head_id)?;
// after
if is_dirty(&workdir)? {
stash::save_manual(path, bare, workdir, head_id)?;
} Defensive patterns
Strategy: validation
Validate before calling
if !tix::edit::review::is_dirty(&workdir)? {
// nothing to stash; skip the operation entirely
return Ok(());
} Try / catch
if let Err(e) = stash::save_manual(path, bare, workdir, head_id) {
if !e.to_string().contains("no worktree or index changes") {
return Err(e.into());
} // clean tree: treat as no-op
} Prevention
- Call `is_dirty` on the worktree before stashing
- Don't stash in scripts after commits or prior stashes may have consumed the changes
- Treat a clean worktree as an expected, skippable condition rather than an error
When it happens
Trigger: Calling `stash::save_manual` (CLI `tix stash`) when the working tree is clean and the index matches HEAD — no modifications, additions, or deletions detected by `is_dirty`.
Common situations: Running stash in a script after changes were already committed or stashed; automation that assumes changes exist; testing against a freshly cloned clean worktree.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Need a worktree to clean, this is a bare repository
- JSON output isn't implemented yet
- a tree change cannot be amended from the worktree
- cannot delete because another worktree has it checked out
- a detached checked-out root commit cannot be removed
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/d250e65a2ef5dbde.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/stash.rs:147
if head != id {
anyhow::bail!("changes can only be stashed at the current HEAD");
}
if repo
.index_or_empty()
.context("could not inspect the index before stashing")?
.entries()
.iter()
.any(|entry| entry.stage() != gix::index::entry::Stage::Unconflicted)
{
anyhow::bail!("cannot stash changes with unresolved index conflicts");
}
let name = reference(id)?;
if repo.try_find_reference(name.as_ref())?.is_some() {
anyhow::bail!("{} already has saved worktree state", id.to_hex_with_len(7));
}
drop(repo);
if !super::review::is_dirty(&workdir)? {
anyhow::bail!("there are no worktree or index changes to stash");
}
let saved = save(
repository_path,
bare,
&workdir,
name,
format!("tix {}", id.to_hex_with_len(7)),
"tix commit stash",
"commit state",
)?;
let mut notice = format!("stashed changes at {}", id.to_hex_with_len(7));
if let Some(warning) = saved.warning {
write!(notice, "; {warning}").expect("writing to a string cannot fail");
}
Ok(notice)
}
#[tracing::instrument(skip_all, fields(commit_id = %id))]View on GitHub (pinned to e73179060b)