GitoxideLabs/gitoxide · error
the rebase todo contains more than one state anchor
Error message
the rebase todo contains more than one state anchor
What it means
A valid rebase todo must contain exactly one state anchor comment. After locating and closing the first anchor, `parse_state` checks whether another `STATE_START` occurs after it; a second anchor means the todo file is malformed (duplicated state blocks) and would make the state ambiguous, so parsing fails.
Solutions
- Open the todo file and delete the duplicate state anchor block, keeping exactly one.
- Restore the todo file from before the conflicting edit/merge.
- Regenerate the todo via tix's rebase preparation to get a clean single anchor.
- Abort the rebase and restart if the todo is unrecoverable.
Example fix
// before // "<!-- tix-rebase-state-v2 base=... -->\n...<!-- tix-rebase-state-v2 base=... -->" let state = parse_state(repo, text)?; // bails // after let cleaned = keep_first_anchor_only(text); let state = parse_state(repo, &cleaned)?;
Defensive patterns
Strategy: validation
Validate before calling
let anchors = todo_text.matches("<!-- tix-rebase-state-").count();
if anchors != 1 {
anyhow::bail!("expected exactly 1 state anchor, found {anchors}");
} Try / catch
match parse(repo, todo_text) {
Ok(s) => s,
Err(e) if e.to_string().contains("more than one state anchor") => {
// repair the todo (keep one anchor) and retry
}
Err(e) => return Err(e),
} Prevention
- Never append or paste content containing a state anchor into a todo
- Resolve todo-file merge conflicts by keeping a single anchor block
- Generate todos only through tix, not by concatenation
When it happens
Trigger: Calling `parse`/`parse_state` on a todo string where the state anchor comment `<!-- tix-rebase-state-... -->` appears more than once — e.g. the file was concatenated, a merge conflict duplicated the block, or tooling appended a second state section.
Common situations: A merge of two branches both editing the todo file duplicated the anchor; an editor or script accidentally appended the state block twice; a user pasted a todo template containing an existing anchor.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- the rebase state has more than one base
- the rebase state has more than one onto target
- the rebase todo uses an unsupported state version
- cannot find character that we didn't search for
- (re-raised revision-spec parse error via bail!(err))
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/3d7a813d053881ac.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/todo.rs:667
.shorten()
.context("could not shorten a rebase todo ID")?
.to_string())
}
}
fn parse_state(repo: &gix::Repository, input: &str) -> Result<Option<State>> {
let Some(start) = input.find(STATE_START) else {
if input.contains("<!-- tix-rebase-state-") {
anyhow::bail!("the rebase todo uses an unsupported state version");
}
return Ok(None);
};
let body = &input[start + STATE_START.len()..];
let end = body
.find(STATE_CLOSE)
.context("the rebase state anchor is not closed")?;
if body[end + STATE_CLOSE.len()..].contains(STATE_START) {
anyhow::bail!("the rebase todo contains more than one state anchor");
}
let mut base = None;
let mut onto = None;
let mut tips = Vec::new();
let mut scope = Vec::new();
let mut marker_required = None;
let mut checkout_allowed = None;
let mut head_ref = None;
let mut edit_refs = false;
let mut expected_refs = Vec::new();
let mut resolved = None;
let mut continuation_sources = Vec::new();
for line in body[..end].lines() {
let (key, value) = line.split_once(' ').context("a rebase state line has no value")?;
match key {
"base" => {
if base.replace(ObjectId::from_hex(value.as_bytes())?).is_some() {
anyhow::bail!("the rebase state has more than one base");View on GitHub (pinned to e73179060b)