GitoxideLabs/gitoxide · error

HEAD has no in the default Tix view

Error message

HEAD has no {} in the default Tix view

What it means

When navigating relatively (parent, child, first, tip, etc.) no unique candidate exists in the default view: either there is no such neighbor (empty list) or the direction is ambiguous. For the empty case tix bails with 'HEAD has no {parent|child|...} in the default Tix view'.

Solutions

  1. Check the direction makes sense at HEAD (e.g. no parent at the root commit)
  2. Unhide revisions that may have removed the neighbor from the default view
  3. Use an absolute OID or a different relative target (first/tip) instead

Example fix

// before
tix travel ^   # HEAD is root commit
// after
tix travel tip   # or target an explicit OID
Defensive patterns

Strategy: validation

Validate before calling

// Check HEAD is not at the boundary before a relative step
let at_root = graph.parents(head_id).is_empty();
if to == To::Parent && at_root {
    return Err(anyhow!("HEAD is the root commit; no parent exists"));
}

Try / catch

if let Err(e) = travel("^") {
    if e.to_string().contains("has no ") {
        eprintln!("direction unavailable here; use first/tip or an OID");
    }
}

Prevention

When it happens

Trigger: `tix travel` with a relative To::* target where visible_parents/children/first/tip candidate computation returns an empty slice in relative_destination().

Common situations: Travelling to a parent at the root commit; requesting a child at a tip; hidden revisions removing the only neighbor from the view.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/4ae1214632b011ab. Report an issue: GitHub.

Appendix: source

Thrown at gix-tix/src/command/travel.rs:161

        .collect::<Vec<_>>();
    let stored = order.iter().copied().collect::<HashSet<_>>();
    if !stored.contains(&head) {
        anyhow::bail!("HEAD is not present in the default Tix view");
    }

    let candidates = match to {
        To::Parent => visible_parents(graph, head, &stored),
        To::Child => order
            .iter()
            .copied()
            .filter(|id| graph.parents_of(*id).is_some_and(|parents| parents.contains(&head)))
            .collect(),
        To::First => first_candidates(graph, head, &stored, &order),
        To::Tip => terminal_candidates(head, &children_by_parent(graph, &stored, &order), &order),
    };
    match candidates.as_slice() {
        [candidate] => Ok(*candidate),
        [] => anyhow::bail!("HEAD has no {} in the default Tix view", to.name()),
        candidates => {
            let candidates = candidates
                .iter()
                .map(|id| crate::change_id::display_short(repository, *id))
                .collect::<Result<Vec<_>>>()?
                .join("\n  ");
            anyhow::bail!(
                "--to {} is ambiguous; candidates:\n  {candidates}\ntravel to one directly with `tix travel REVSPEC`",
                to.name()
            )
        }
    }
}

fn visible_parents(
    graph: &crate::history::HistoryGraph,
    id: gix::ObjectId,
    stored: &HashSet<gix::ObjectId>,

View on GitHub (pinned to e73179060b)