GitoxideLabs/gitoxide · error

unknown commit header

Error message

unknown commit header: {}

What it means

After the fixed enrichment headers, every remaining header-position line must be a recognized `Todo` or `Message` line. Any other non-comment line before the blank separator is rejected by `parse` with this error, echoing the offending line, to prevent silently misinterpreting malformed documents.

Solutions

  1. Remove or fix the unrecognized line so only `Todo`/`Message` headers (and comments) appear before the blank line.
  2. Check the line for typos against the expected header names.
  3. Regenerate the document with `document()` if its structure is unclear or from another tool version.

Example fix

// before
Todo
Mesage: typo header
pick abc123 msg
// after
Todo
pick abc123 msg
Defensive patterns

Strategy: validation

Validate before calling

fn header_line_known(line: &[u8]) -> bool {
    line == TODO || line.starts_with(MESSAGE)
}

Try / catch

match parse(&edited) {
    Ok(doc) => doc,
    Err(e) if e.to_string().starts_with("unknown commit header") => {
        eprintln!("Edit document contains an unrecognized header line; fix or regenerate it.");
        Err(e)
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `parse` on a document where a line in the header section is neither a comment (per CommentChar), `Todo`, nor the `MESSAGE` prefix — e.g. a stray `pick` line, a typo like `Mesage:`, or a header written before its expected position.

Common situations: Hand-edited documents with typos; older/newer document formats mixed after a version change; tools inserting their own headers into the enrichment block.

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


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

Appendix: source

Thrown at gix-tix/src/edit/reword.rs:389

            message_offset = Some(consumed);
            break;
        }
        if line.starts_with(comment_char) {
            continue;
        }
        if line == TODO {
            if std::mem::replace(&mut todo_seen, true) {
                anyhow::bail!("duplicate Todo header");
            }
            enrichment.todo = true;
        } else if let Some(title) = line.strip_prefix(MESSAGE) {
            if std::mem::replace(&mut message_seen, true) {
                anyhow::bail!("duplicate Message header");
            }
            let title = title.trim();
            enrichment.message = (!title.is_empty()).then(|| title.into());
        } else {
            anyhow::bail!("unknown commit header: {}", line.as_bstr());
        }
    }
    let message_offset = message_offset.context("expected an empty line after the commit headers")?;
    let message = cleanup_message(
        remainder
            .get(message_offset..)
            .context("the commit message is missing")?,
        Some(comment_char),
    );
    Ok(Edit {
        author,
        author_time,
        committer,
        committer_time,
        message,
        enrichment,
    })
}

View on GitHub (pinned to e73179060b)