{"record":{"id":"3d7a813d053881ac","repo":"GitoxideLabs/gitoxide","slug":"the-rebase-todo-contains-more-than-one-state-ancho","errorCode":null,"errorMessage":"the rebase todo contains more than one state anchor","messagePattern":"the rebase todo contains more than one state anchor","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/todo.rs","lineNumber":667,"sourceCode":"            .shorten()\n            .context(\"could not shorten a rebase todo ID\")?\n            .to_string())\n    }\n}\n\nfn parse_state(repo: &gix::Repository, input: &str) -> Result<Option<State>> {\n    let Some(start) = input.find(STATE_START) else {\n        if input.contains(\"<!-- tix-rebase-state-\") {\n            anyhow::bail!(\"the rebase todo uses an unsupported state version\");\n        }\n        return Ok(None);\n    };\n    let body = &input[start + STATE_START.len()..];\n    let end = body\n        .find(STATE_CLOSE)\n        .context(\"the rebase state anchor is not closed\")?;\n    if body[end + STATE_CLOSE.len()..].contains(STATE_START) {\n        anyhow::bail!(\"the rebase todo contains more than one state anchor\");\n    }\n    let mut base = None;\n    let mut onto = None;\n    let mut tips = Vec::new();\n    let mut scope = Vec::new();\n    let mut marker_required = None;\n    let mut checkout_allowed = None;\n    let mut head_ref = None;\n    let mut edit_refs = false;\n    let mut expected_refs = Vec::new();\n    let mut resolved = None;\n    let mut continuation_sources = Vec::new();\n    for line in body[..end].lines() {\n        let (key, value) = line.split_once(' ').context(\"a rebase state line has no value\")?;\n        match key {\n            \"base\" => {\n                if base.replace(ObjectId::from_hex(value.as_bytes())?).is_some() {\n                    anyhow::bail!(\"the rebase state has more than one base\");","sourceCodeStart":649,"sourceCodeEnd":685,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/todo.rs#L649-L685","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n// \"<!-- tix-rebase-state-v2 base=... -->\\n...<!-- tix-rebase-state-v2 base=... -->\"\nlet state = parse_state(repo, text)?; // bails\n\n// after\nlet cleaned = keep_first_anchor_only(text);\nlet state = parse_state(repo, &cleaned)?;","handlingStrategy":"validation","validationCode":"let anchors = todo_text.matches(\"<!-- tix-rebase-state-\").count();\nif anchors != 1 {\n    anyhow::bail!(\"expected exactly 1 state anchor, found {anchors}\");\n}","typeGuard":null,"tryCatchPattern":"match parse(repo, todo_text) {\n    Ok(s) => s,\n    Err(e) if e.to_string().contains(\"more than one state anchor\") => {\n        // repair the todo (keep one anchor) and retry\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["parsing","rebase","malformed-input","duplication"],"backgroundTag":"schema-validation-failed","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"}