GitoxideLabs/gitoxide · error
CommentChar must not contain a line ending
Error message
CommentChar must not contain a line ending
What it means
The reword edit document carries enrichment headers, one of which is `CommentChar`. Because comment lines are detected by line-start prefix matching, a comment character containing `\r` or `\n` would corrupt line parsing. `parse` therefore rejects any CommentChar value containing a line ending with this error.
Solutions
- Set CommentChar to a single non-line-ending character (e.g. `#`).
- Normalize line endings (CRLF → LF) before writing/parsing the document.
- Regenerate the edit document via `document()` instead of hand-editing headers.
Example fix
// before (document header with CR leaking in) CommentChar: #\r // after (normalize before parsing) let normalized: Vec<u8> = edited.iter().copied().filter(|&b| b != b'\r').collect(); parse(&normalized)?;
Defensive patterns
Strategy: validation
Validate before calling
fn comment_char_is_safe(value: &[u8]) -> bool {
!value.contains(&b'\n') && !value.contains(&b'\r')
} Try / catch
match parse(&edited) {
Ok(doc) => doc,
Err(e) if e.to_string().contains("CommentChar") => {
let sanitized: Vec<u8> = edited.iter().copied().filter(|&b| b != b'\r').collect();
parse(&sanitized)
}
Err(e) => return Err(e),
} Prevention
- Always use a single printable character (typically `#`) as CommentChar.
- Normalize CRLF to LF before writing or parsing edit documents.
- Generate documents via `document()` instead of hand-writing headers.
When it happens
Trigger: Calling `parse` (via `apply_conflict_reporting`, `parses_the_edit_document`, `document_does_not_repeat_existing_agent_trailers`, or `parses_bare_todo_and_single_line_message_headers`) on a document whose `CommentChar` header value contains a `\r` (checked here) or other line-ending byte.
Common situations: A document generated on/for Windows with CRLF leaking into the header value; a custom comment character mistakenly configured as a multi-character or control-character string; hand-edited enrichment headers.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- duplicate Todo header
- duplicate Message header
- unknown commit header
- lines in ' ' could not be parsed
- Invalid pathspec - path must not be empty, not be excluded…
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/00a8b2c8dbadebce.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/reword.rs:359
out.extend_from_slice(label);
out.extend_from_slice(
time.format(gix::date::time::format::ISO8601)
.context("could not format commit date")?
.as_bytes(),
);
out.push(b'\n');
Ok(())
}
pub(super) fn parse(input: &[u8]) -> Result<Edit<'_>> {
let mut parts = input.splitn(6, |byte| *byte == b'\n');
let author = header(parts.next(), AUTHOR)?;
let author_time = date(header(parts.next(), AUTHOR_DATE)?, "author")?;
let committer = header(parts.next(), COMMITTER)?;
let committer_time = date(header(parts.next(), COMMITTER_DATE)?, "committer")?;
let comment_char = header(parts.next(), COMMENT_CHAR)?;
if comment_char.contains(&b'\r') {
anyhow::bail!("CommentChar must not contain a line ending");
}
let remainder = parts.next().context("the enrichment headers are missing")?;
let mut enrichment = crate::enrich::Headers::default();
let mut todo_seen = false;
let mut message_seen = false;
let mut message_offset = None;
let mut consumed = 0;
for line in remainder.lines_with_terminator() {
consumed += line.len();
let line = trim_cr(line.strip_suffix(b"\n").unwrap_or(line));
if line.is_empty() {
message_offset = Some(consumed);
break;
}
if line.starts_with(comment_char) {
continue;
}
if line == TODO {View on GitHub (pinned to e73179060b)