{"record":{"id":"68749461809aa807","repo":"Hmbown/CodeWhale","slug":"failed-to-read-git-range-commit-range-r-exc","errorCode":null,"errorMessage":"failed to read git range {commit_range!r}: {exc}","messagePattern":"failed to read git range (.+?): (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"scripts/check-coauthor-trailers.py","lineNumber":176,"sourceCode":"        if login := github_login_from_noreply(identity.email):\n            aliases.setdefault(norm_key(login), identity)\n    return aliases\n\n\ndef git_log(commit_range: str) -> list[Commit]:\n    try:\n        raw = subprocess.check_output(\n            [\n                \"git\",\n                \"log\",\n                \"--format=%H%x00%P%x00%an%x00%ae%x00%s%x00%B%x1e\",\n                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()","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/check-coauthor-trailers.py#L158-L194","documentation":"The checker shells out to 'git log --format=...' over a commit range (default the PR/push range passed as argv) inside the repo root. When git exits non-zero — subprocess.CalledProcessError — it is re-raised as this RuntimeError echoing the exact range, so a bad range fails loudly instead of silently validating nothing.","triggerScenarios":"Passing a malformed or unknown range: 'HEAD..nonexistent-branch', a SHA that does not exist (shallow clone), 'origin/main' when the remote ref is absent, or an empty range string that git rejects. Local dirty state does not matter; only git log's exit code does.","commonSituations":"Running the script in CI on a shallow clone missing the base ref; typo'd branch names; rebases that rewrote the range so the old tip SHA is unreachable; invoking with no range argument where the script then uses a default that doesn't exist locally.","solutions":["Run 'git log <same range>' manually in the repo root; git's own stderr will name the bad ref.","Fetch the missing base ref first (git fetch origin <base>) or pass a range that exists locally, e.g. 'origin/main..HEAD'.","In shallow CI clones, fetch with enough depth (fetch --unshallow or --deepen) to cover the range.","Confirm the range syntax: A..B (two-dot excluded range) with valid refs/SHAs on both sides."],"exampleFix":"# before\npython3 scripts/check-coauthor-trailers.py HEAD..feature/nonexistent-tip\n# after\ngit fetch origin main\npython3 scripts/check-coauthor-trailers.py origin/main..HEAD","handlingStrategy":"try-catch","validationCode":"import subprocess\n\ndef range_is_readable(commit_range: str) -> bool:\n    return subprocess.run(\n        [\"git\", \"rev-parse\", \"--verify\", \"--quiet\", commit_range],\n        capture_output=True,\n    ).returncode == 0","typeGuard":null,"tryCatchPattern":"try:\n    commits = git_log(commit_range)\nexcept RuntimeError as error:\n    if \"failed to read git range\" in str(error):\n        subprocess.run([\"git\", \"fetch\", \"--deepen=100\"], check=False)\n        commits = git_log(commit_range)  # retry once after deepening\n    else:\n        raise","preventionTips":["Fetch the base ref and enough depth before running range checks in shallow clones.","Prefer explicit two-ref ranges like origin/main..HEAD over raw SHAs that may be unreachable.","Test the range with 'git log <range> --oneline' first when in doubt."],"tags":["git","ci","subprocess","refs"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}