Hmbown/CodeWhale · error · RuntimeError

failed to parse git log output

Error message

failed to parse git log output

What it means

git log output is framed with %x1e record separators and %x00 field separators, and each record must split into exactly 6 fields: hash, parents, author name, author email, subject, body. This internal parse error means a record did not yield 6 NUL-separated parts, indicating the framing assumptions broke rather than a user data problem.

Source

Thrown at scripts/check-coauthor-trailers.py:188

                commit_range,
            ],
            cwd=ROOT,
            text=True,
        )
    except subprocess.CalledProcessError as exc:
        raise RuntimeError(f"failed to read git range {commit_range!r}: {exc}") from exc

    commits: list[Commit] = []
    for record in raw.split("\x1e"):
        if not record.strip():
            continue
        # `git log` emits a newline after each record separator. Remove only
        # that framing byte so the next record's full SHA remains exact while
        # preserving commit-body whitespace.
        record = record.lstrip("\n")
        parts = record.split("\x00", 5)
        if len(parts) != 6:
            raise RuntimeError("failed to parse git log output")
        commits.append(Commit(*parts))
    return commits


def is_bot_identity(name: str, email: str) -> bool:
    lowered_name = name.strip().lower()
    lowered_email = email.strip().lower()
    return lowered_email in BOT_EMAILS or any(
        lowered_name == bot or lowered_name.startswith(f"{bot} ") for bot in BOT_NAMES
    )


def lookup_identity(aliases: dict[str, Identity], *values: str) -> Identity | None:
    for value in values:
        identity = aliases.get(norm_key(value))
        if identity is not None:
            return identity
    return None

View on GitHub (pinned to 8880682c63)

Solutions

  1. Run 'git log --format=%H%x00%P%x00%an%x00%ae%x00%s%x00%B%x1e <range>' and inspect which record has extra \x00 or \x1e bytes.
  2. Rewrite the offending commit message to strip embedded NUL/0x1E bytes (git commit --amend or filter-branch for history).
  3. Verify git version compatibility if the output framing looks shifted.
  4. If embedded control bytes must be tolerated, extend the parser to split on the first five NULs and validate — but treat that as a contract change with tests.
Defensive patterns

Strategy: try-catch

Validate before calling

def records_parse(records: list[str]) -> bool:
    return all(len(r.lstrip("\n").split("\x00", 5)) == 6 for r in records if r.strip())

Try / catch

try:
    commits = git_log(commit_range)
except RuntimeError as error:
    if "failed to parse git log output" in str(error):
        # binary control bytes in commit messages — find the offending commit
        raw = subprocess.check_output(["git", "log", "--format=%H %B", commit_range], text=True)
        suspects = [l for l in raw.splitlines() if "\x00" in l or "\x1e" in l]
        logger.error("control bytes in commit messages: %s", suspects)
    raise

Prevention

When it happens

Trigger: A commit message body containing a literal NUL (0x00) or record separator (0x1e) byte adds extra splits; git version differences emitting unexpected framing; corrupted objects in the repository making git log emit malformed records. The code deliberately strips only the leading newline framing byte to preserve body whitespace, so embedded NULs are the classic breaker.

Common situations: Commits created by tooling that embeds binary data or control characters into messages; piping the script's git output through a tool that mangles bytes; extremely unusual commit metadata. This is rare — hitting it usually means something wrote raw bytes into commit messages.

Understand the failure class

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/3043245a3be60042. Report an issue: GitHub.