Hmbown/CodeWhale · error · PersistenceBacklogError
persistence measurement source tree is dirty
Error message
persistence measurement source tree is dirty
What it means
When the checker runs with `require_clean_source=True` (always in main for the measured/receipt check), the receipt's `source_dirty` flag must be false. A dirty tree means the measurement may not correspond to any committed source revision, so performance numbers are not reproducible and the budget comparison would be untrustworthy. The error fires when the receipt records uncommitted changes at measurement time.
Solutions
- Commit or stash all changes (including untracked files, or add them to .gitignore) and re-run the measurement so source_dirty is false
- Regenerate the receipt on a clean tree: `git status --porcelain` must output nothing before measuring
- Remove or ignore stray generated files that make `git status` non-empty
Example fix
// before $ git status --porcelain M crates/tui/src/main.rs $ python scripts/check-persistence-backlog-budget.py ERROR: persistence measurement source tree is dirty // after $ git stash -u $ python scripts/check-persistence-backlog-budget.py PASS: one-way ceilings respected
Defensive patterns
Strategy: validation
Validate before calling
import subprocess dirty = bool(subprocess.run(["git","status","--porcelain","--untracked-files=normal"], capture_output=True, text=True).stdout.strip()) assert not dirty, "commit/stash changes before measuring"
Try / catch
try:
compare(receipt, budget, require_clean_source=True)
except PersistenceBacklogError as e:
if "source tree is dirty" in str(e):
stash_or_commit_then_remeasure() Prevention
- Run `git status --porcelain` before measuring; require empty output
- Commit or stash -u before running budget checks (untracked files count as dirty)
- Add generated artifacts to .gitignore so they do not dirty the tree
- Make the clean-tree check part of CI so local dirt never produces receipts
When it happens
Trigger: Running the checker with uncommitted edits in the working tree; a receipt generated on a dirty tree is later validated with require_clean_source; untracked files present when `git status --porcelain --untracked-files=normal` runs (untracked files count as dirty).
Common situations: Editing code, then running the persistence check before committing; CI artifacts (logs, build outputs) left in the tree; checking out a receipt generated during local experimentation.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- baseline provenance must identify a clean source tree
- baseline provenance needs an exact source SHA
- expected revision must be an exact 40-character Git SHA
- gh pr view did not return exact base and head commit IDs
- GitHub tag ref did not include an object SHA
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/296882440a24ab0f.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/check-persistence-backlog-budget.py:178
if not isinstance(receipt[field], str) or not receipt[field].startswith(prefix):
raise PersistenceBacklogError(f"receipt {field} must be a version string")
validate_frozen_field("build_profile", receipt["build_profile"], "test")
validate_frozen_field("sample_count", receipt["sample_count"], 1)
if expected_source is not None:
for field in (
"source_sha",
"source_dirty",
"rustc_version",
"cargo_version",
"build_profile",
"sample_count",
):
if receipt[field] != expected_source[field]:
raise PersistenceBacklogError(
f"receipt {field} does not match the checked source"
)
if require_clean_source and receipt["source_dirty"]:
raise PersistenceBacklogError("persistence measurement source tree is dirty")
platform = receipt["platform"]
if not isinstance(platform, str) or platform not in SUPPORTED_PLATFORMS:
raise PersistenceBacklogError("receipt platform is unsupported")
attempted = non_negative_integer(receipt["requests_attempted"], "requests_attempted")
accepted = non_negative_integer(receipt["accepted_requests"], "accepted_requests")
if accepted != attempted:
raise PersistenceBacklogError(
"accepted_requests must equal requests_attempted; sender rejection is not backlog improvement"
)
retained = non_negative_integer(
receipt["retained_queued_requests"], "retained_queued_requests"
)
if retained > accepted:
raise PersistenceBacklogError("retained_queued_requests exceeds accepted_requests")
for field in ("estimated_retained_payload_bytes", "enqueue_elapsed_ns"):
non_negative_integer(receipt[field], field)
if retained == 0 or receipt["estimated_retained_payload_bytes"] == 0:View on GitHub (pinned to 433685b202)