{"record":{"id":"3043245a3be60042","repo":"Hmbown/CodeWhale","slug":"failed-to-parse-git-log-output","errorCode":null,"errorMessage":"failed to parse git log output","messagePattern":"failed to parse git log output","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"scripts/check-coauthor-trailers.py","lineNumber":188,"sourceCode":"                commit_range,\n            ],\n            cwd=ROOT,\n            text=True,\n        )\n    except subprocess.CalledProcessError as exc:\n        raise RuntimeError(f\"failed to read git range {commit_range!r}: {exc}\") from exc\n\n    commits: list[Commit] = []\n    for record in raw.split(\"\\x1e\"):\n        if not record.strip():\n            continue\n        # `git log` emits a newline after each record separator. Remove only\n        # that framing byte so the next record's full SHA remains exact while\n        # preserving commit-body whitespace.\n        record = record.lstrip(\"\\n\")\n        parts = record.split(\"\\x00\", 5)\n        if len(parts) != 6:\n            raise RuntimeError(\"failed to parse git log output\")\n        commits.append(Commit(*parts))\n    return commits\n\n\ndef is_bot_identity(name: str, email: str) -> bool:\n    lowered_name = name.strip().lower()\n    lowered_email = email.strip().lower()\n    return lowered_email in BOT_EMAILS or any(\n        lowered_name == bot or lowered_name.startswith(f\"{bot} \") for bot in BOT_NAMES\n    )\n\n\ndef lookup_identity(aliases: dict[str, Identity], *values: str) -> Identity | None:\n    for value in values:\n        identity = aliases.get(norm_key(value))\n        if identity is not None:\n            return identity\n    return None","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/check-coauthor-trailers.py#L170-L206","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Rewrite the offending commit message to strip embedded NUL/0x1E bytes (git commit --amend or filter-branch for history).","Verify git version compatibility if the output framing looks shifted.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"def records_parse(records: list[str]) -> bool:\n    return all(len(r.lstrip(\"\\n\").split(\"\\x00\", 5)) == 6 for r in records if r.strip())","typeGuard":null,"tryCatchPattern":"try:\n    commits = git_log(commit_range)\nexcept RuntimeError as error:\n    if \"failed to parse git log output\" in str(error):\n        # binary control bytes in commit messages — find the offending commit\n        raw = subprocess.check_output([\"git\", \"log\", \"--format=%H %B\", commit_range], text=True)\n        suspects = [l for l in raw.splitlines() if \"\\x00\" in l or \"\\x1e\" in l]\n        logger.error(\"control bytes in commit messages: %s\", suspects)\n    raise","preventionTips":["Never allow raw NUL (0x00) or record-separator (0x1E) bytes into commit messages.","Sanitize generated commit bodies (strip control characters) before committing.","Treat this error as a data-integrity signal: locate the offending commit and rewrite it rather than patching the parser."],"tags":["git","parsing","binary-data","internal"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}