{"record":{"id":"564600bd353c95b5","repo":"GitoxideLabs/gitoxide","slug":"the-rebase-todo-contains-more-than-one-command","errorCode":null,"errorMessage":"the rebase todo contains more than one @ command","messagePattern":"the rebase todo contains more than one @ command","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/todo.rs","lineNumber":928,"sourceCode":"            }\n            section_has_commit = true;\n            continue;\n        }\n\n        let (command, tail) = if let Some(line) = line.strip_prefix('`') {\n            let (command, tail) = line\n                .split_once('`')\n                .context(\"a Markdown todo command has no closing backtick\")?;\n            (command, tail.trim())\n        } else {\n            (line, \"\")\n        };\n        let (verb, value) = command.split_once(char::is_whitespace).unwrap_or((command, \"\"));\n        let marked = verb.starts_with('@');\n        let verb = verb.strip_prefix('@').unwrap_or(verb);\n        if marked {\n            if std::mem::replace(&mut command_marker, true) {\n                anyhow::bail!(\"the rebase todo contains more than one @ command\");\n            }\n            if !state.checkout_allowed || repo.workdir().is_none() {\n                anyhow::bail!(\"the rebase todo cannot select a checkout without a worktree\");\n            }\n        }\n        if verb == \"squash\" {\n            let index = section_last_step.context(\"a squash must follow a command in the same fork\")?;\n            let id = resolve_commit(\n                repo,\n                value.split_whitespace().next().context(\"a squash needs a commit ID\")?,\n            )?;\n            if !scope.contains(&id) {\n                anyhow::bail!(\"a squash is outside the editable history\");\n            }\n            if picked.insert(id, index).is_some() {\n                anyhow::bail!(\"a commit is picked more than once\");\n            }\n            steps[index].squash.push(id);","sourceCodeStart":910,"sourceCodeEnd":946,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/todo.rs#L910-L946","documentation":"This error is thrown by the rebase todo parser in gix-tix when a todo script marks more than one line with an `@` prefix. The `@` marker selects the result of a command as the checkout target of the edited plan, and exactly one such marker is allowed. The parser uses a `command_marker` flag and bails once a second marked line is seen.","triggerScenarios":"Calling `parse_plan` (via the todo editing API) with a rebase todo file in which two or more lines start with `@` (e.g. `@pick abc123` and `@pick def456`).","commonSituations":"Hand-editing a rebase todo and marking two commands with `@` by mistake; scripting todo generation where the marker is added per-command instead of only for the final checkout target.","solutions":["Remove all but one `@` prefix from the todo, leaving it only on the command whose result should be checked out","If multiple checkouts are needed, split the operation into several plan edits","Validate the todo text before parsing by counting lines whose first token starts with `@`"],"exampleFix":"// before\n@pick abc123\n@pick def456\n// after\n@pick abc123\npick def456","handlingStrategy":"validation","validationCode":"let marked = todo.lines().filter(|l| l.split_whitespace().next().map_or(false, |v| v.starts_with('@'))).count();\nif marked > 1 { anyhow::bail!(\"todo has {} @-marked commands; only one is allowed\", marked); }","typeGuard":"fn marked_commands(todo: &str) -> Vec<&str> {\n    todo.lines().filter(|l| l.split_whitespace().next().map_or(false, |v| v.starts_with('@'))).collect()\n}","tryCatchPattern":"match parse_plan(...) {\n    Err(e) if e.to_string().contains(\"more than one @ command\") => { /* strip extra @ markers and retry */ }\n    other => other?,\n}","preventionTips":["Keep at most one `@` marker per todo and place it on the final intended checkout command","Count @-prefixed first tokens before parsing","Generate todos programmatically instead of hand-editing"],"tags":["git","rebase","todo-parsing","validation"],"backgroundTag":"invalid-argument-format","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"}