666ghj/MiroFish · error · StarHistoryError

{relative} is not synchronized with history.json

Error message

{relative} is not synchronized with history.json

What it means

Raised by check_workspace (called at the end of _write_outputs and usable standalone): it reloads history.json canonically, regenerates the expected light/dark SVGs via _output_payloads, and byte-compares them against the files on disk. Any byte difference means the committed SVGs are not exactly what the current state would render — a drift guard that keeps history.json and the two SVGs in lockstep as a single atomic unit.

Source

Thrown at scripts/star_history.py:1357

        for temporary in temporary_paths.values():
            try:
                temporary.unlink(missing_ok=True)
            except OSError:
                pass

    check_workspace(workspace)
    return True


def check_workspace(workspace: Path) -> None:
    state = load_state(workspace, require_canonical=True)
    expected = _output_payloads(state)
    for relative in OUTPUT_RELATIVES[1:]:
        target = _safe_target(workspace, relative, create_parent=False)
        actual = _read_limited(target, MAX_STATE_BYTES, str(relative))
        _validate_svg(actual)
        if actual != expected[relative]:
            raise StarHistoryError(f"{relative} is not synchronized with history.json")


def execute(
    command: str,
    *,
    github: GitHubGateway | None,
    clock: Clock,
    workspace: Path,
    force: bool = False,
    star_count: int | None = None,
) -> Result:
    root = _safe_workspace(workspace)
    now = _normalize_now(clock.now())

    if command == "backfill":
        state_target = _safe_target(root, STATE_RELATIVE, create_parent=False)
        if state_target.exists():
            raise StarHistoryError("history state already exists; refusing to overwrite backfill")

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Never edit the SVGs by hand — regenerate both via the script so all three files update together (e.g. re-run the update/refresh command that calls _write_outputs).
  2. If state is correct and the SVGs are stale, re-run the generator; it rewrites the SVGs to match history.json byte-for-byte.
  3. If a template change altered rendering, commit the regenerated SVGs in the same commit as the template/validator change.
  4. Check for tooling that rewrites the files (prettier, editors stripping trailing newlines, CRLF conversion on Windows checkouts) and exclude these generated files from it (.gitattributes: *.svg -text or export-ignore formatters).

Example fix

# before: manual SVG edit drifted from state
$ nano static/image/star-history-light.svg   # tweak color
$ git commit -am 'tweak'
# -> '{relative} is not synchronized with history.json' on next check

# after: change the template, then regenerate all outputs atomically
$ edit scripts/star_history.py   # template + allowlist
$ python scripts/star_history.py <update-command>   # rewrites all three files
Defensive patterns

Strategy: validation

Validate before calling

def outputs_in_sync(workspace: Path) -> bool:
    try:
        check_workspace(workspace)
        return True
    except StarHistoryError:
        return False

# cheap preflight in CI before any commit that touches these files
assert outputs_in_sync(root), "SVGs drifted from history.json; regenerate before committing"

Try / catch

try:
    check_workspace(workspace)
except StarHistoryError as exc:
    if "not synchronized" in str(exc):
        # regenerate all three outputs via the script (never hand-patch one file)
        # then commit them together
        ...

Prevention

When it happens

Trigger: Hand-editing static/image/star-history-light.svg or -dark.svg (tweaking colors, removing the watermark) without touching history.json; committing an SVG from an older version of the generator after the template changed; a partial/interrupted older write that left new SVGs with old state (or vice versa); reformatting line endings or trailing newlines.

Common situations: A designer 'fixes' the SVG directly in an editor; a merge conflict resolves history.json from one branch and the SVGs from another; CI regenerates with a different Python/dependency version producing different float formatting; lint/formatter tools normalizing SVG whitespace.

Related errors


AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14). Data as JSON: /api/errors/fad9861c3d958d80. Report an issue: GitHub.