GitoxideLabs/gitoxide · error
change ID is no longer present in the Tix view
Error message
change ID {change_id} is no longer present in the Tix view What it means
In `gix-tix`'s reword flow, `relocate_after_editor` maps the change ID recorded before the editor ran back to a commit currently visible in the Tix view. When the mapping walk over commits produces zero matches, the change ID no longer corresponds to any commit that can be relocated onto, so the operation is aborted with this message. This guards against rewriting onto a commit that was concurrently amended, rebased away, or deleted.
Solutions
- Re-read the current Tix view (refresh state) and retry the reword against the new commit graph.
- Check for concurrent operations (another gix-tix process, an amend) that rewrote the target commit while the editor was open, and re-run after they finish.
- Verify the change ID with `crate::change_id::display_short` / inspect recent history to find where the commit went, then re-apply the reword to the correct commit.
- If the commit was intentionally dropped, cancel the reword instead of relocating it.
Example fix
// before: assuming the pre-edit change ID is still valid
let (graph, target) = relocate_after_editor(repo, change_id)?;
// after: re-resolve after concurrent rewrites and bail gracefully
match relocate_after_editor(repo, change_id) {
Ok((graph, target)) => apply(graph, target),
Err(_) => {
// refresh view / re-run `gix tix` so change_id maps to the amended commit
refresh_view(repo)?;
relocate_after_editor(repo, change_id)
}
} Defensive patterns
Strategy: retry
Validate before calling
fn change_id_still_visible(repo: &gix::Repository, change_id: &ChangeId) -> bool {
crate::change_id::for_commit(repo, head_commit_id(repo)).map(|id| id == *change_id).unwrap_or(false)
} Try / catch
match relocate_after_editor(repo, change_id) {
Ok((graph, target)) => proceed(graph, target),
Err(e) if e.to_string().contains("no longer present") => refresh_view_and_retry(repo, change_id),
Err(e) => return Err(e),
} Prevention
- Do not run concurrent history-rewriting operations (amend/rebase) while an editor-backed reword is in flight.
- Refresh the Tix view immediately before starting a reword.
- Treat change IDs as volatile across history rewrites and re-resolve them after any rewrite.
When it happens
Trigger: Calling `relocate_after_editor` (via `relocates_an_editor_reword_onto_a_concurrent_amend` or `editor_relocation_requires_one_visible_commit` paths) when `crate::change_id::for_commit` never equals the recorded `change_id` for any candidate commit — e.g. the original commit was amended concurrently so its change ID no longer matches, or the commit was dropped/rewritten out of the view.
Common situations: A concurrent `amend` rewrote the commit while the external editor was open; a rebase or history rewrite removed the commit between recording the change ID and applying the reword; a stale Tix view/branch state after another tool rewrote history.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- change ID is ambiguous in the Tix view; candidates
- change ID prefix is ambiguous in the default Tix view
- the edited commit message is empty
- duplicate Todo header
- duplicate Message header
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/c07438e1352c9c95.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/reword.rs:63
}
}
pub(crate) fn relocate_after_editor(
repo: &gix::Repository,
revisions: &[std::ffi::OsString],
hidden_revisions: &[std::ffi::OsString],
change_id: gix::hash::ChangeId,
) -> Result<(crate::history::HistoryGraph, gix::ObjectId)> {
let graph = super::loaded_view_graph_with_hidden(repo, revisions, hidden_revisions)?;
let mut matches = Vec::new();
for id in graph.stored_commit_ids() {
if crate::change_id::for_commit(repo, id)? == change_id {
matches.push(id);
}
}
match matches.as_slice() {
[target] => Ok((graph, *target)),
[] => anyhow::bail!("change ID {change_id} is no longer present in the Tix view"),
candidates => {
let candidates = candidates
.iter()
.map(|id| crate::change_id::display_short(repo, *id))
.collect::<Result<Vec<_>>>()?
.join("\n ");
anyhow::bail!("change ID {change_id} is ambiguous in the Tix view; candidates:\n {candidates}")
}
}
}
#[tracing::instrument(skip_all, fields(commit_id = %id))]
pub(crate) fn document(repo: &gix::Repository, id: gix::ObjectId) -> Result<(gix::command::Prepare, Vec<u8>)> {
document_with_author(repo, id, None)
}
pub(crate) fn document_with_author(
repo: &gix::Repository,View on GitHub (pinned to e73179060b)