GitoxideLabs/gitoxide · error
the rebase state repeats marker-required
Error message
the rebase state repeats marker-required
What it means
The rebase todo/state parser in gix-tix (`parse_state`) found a `marker-required` line in the rebase state file, but a `marker-required` line was already seen earlier in the file. The state format allows each scalar field to appear at most once, so a second occurrence is rejected as a malformed or corrupted state file. This prevents silently overwriting a previously recorded value.
Solutions
- Open the rebase state file and remove the duplicate `marker-required` line, keeping exactly one.
- If the state file is corrupted or unclear, abort the operation and let the tool regenerate state from scratch.
- Check for other running gix/gitoxide processes that may have written the state file concurrently.
Example fix
// before (state file) marker-required true marker-required false // after marker-required true
Defensive patterns
Strategy: validation
Validate before calling
fn state_file_is_clean(text: &str) -> bool {
text.lines().filter(|l| l.starts_with("marker-required ")).count() <= 1
} Try / catch
match todo::parse(state_text) {
Ok(state) => apply(state),
Err(e) if e.to_string().contains("repeats marker-required") => {
eprintln!("corrupt state: duplicate marker-required; regenerate state");
}
Err(e) => return Err(e),
} Prevention
- Never hand-edit rebase state files; regenerate them via the tool.
- Keep exactly one line per scalar field when constructing state files programmatically.
- Take the state-file lock (or check for concurrent processes) before writing.
When it happens
Trigger: Parsing a rebase state file via `parse`/`parse_state` (gix-tix/src/edit/todo.rs:697) where two `marker-required <bool>` lines exist. Typically caused by a hand-edited or concurrently-written state file, or by a corrupted `.git/rebase-merge`-style state.
Common situations: Manually editing a rebase state file and accidentally duplicating a line; merge conflicts while a state file was modified; tooling that appends instead of replacing fields; state files copied between worktrees.
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 repeats checkout-allowed
- the rebase state repeats its HEAD ref
- the rebase state repeats its resolved conflict
- the recorded HEAD ref has trailing data
- a captured ref name has trailing data
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/38314ae6eeec06e3.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/todo.rs:697
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");
}
}
"onto" => {
if onto.replace(ObjectId::from_hex(value.as_bytes())?).is_some() {
anyhow::bail!("the rebase state has more than one onto target");
}
}
"tip" => tips.push(ObjectId::from_hex(value.as_bytes())?),
"scope" => scope.push(ObjectId::from_hex(value.as_bytes())?),
"marker-required" => {
if marker_required.replace(value.parse()?).is_some() {
anyhow::bail!("the rebase state repeats marker-required");
}
}
"checkout-allowed" => {
if checkout_allowed.replace(value.parse()?).is_some() {
anyhow::bail!("the rebase state repeats checkout-allowed");
}
}
"head-ref" => {
let encoded = value.as_bytes().as_bstr();
let (name, consumed) = gix::quote::ansi_c::undo(encoded)
.map_err(gix::Exn::into_error)
.context("could not unquote the recorded HEAD ref")?;
if !encoded[consumed..].trim().is_empty() {
anyhow::bail!("the recorded HEAD ref has trailing data");
}
let name = gix::refs::FullName::try_from(name.as_ref()).context("the recorded HEAD ref is invalid")?;
if head_ref.replace(name).is_some() {
anyhow::bail!("the rebase state repeats its HEAD ref");View on GitHub (pinned to e73179060b)