nextlevelbuilder/ui-ux-pro-max-skill · error · ValueError

catalog-summary.json is stale; regenerate it

Error message

catalog-summary.json is stale; regenerate it

What it means

Raised in --check mode when the on-disk catalog-summary.json does not byte-for-byte match the content regenerated from current data plus the resolved verifiedAt timestamp. The check is a deterministic reproducibility guard: same data + same timestamp must produce identical JSON (including indent=2, ensure_ascii=False, and the trailing newline). Any drift means the committed summary is stale.

Source

Thrown at scripts/generate-catalog-summary.py:131

def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--verified-at")
    parser.add_argument("--check", action="store_true")
    args = parser.parse_args()
    try:
        verified_at = args.verified_at
        if args.check and not verified_at:
            if not OUTPUT.exists():
                raise ValueError("catalog-summary.json is missing")
            verified_at = json.loads(OUTPUT.read_text(encoding="utf-8")).get("verifiedAt")
        if not verified_at:
            raise ValueError("--verified-at is required when generating the summary")
        summary = build(verified_at)
        content = json.dumps(summary, ensure_ascii=False, indent=2) + "\n"
        if args.check:
            if not OUTPUT.exists() or OUTPUT.read_text(encoding="utf-8") != content:
                raise ValueError("catalog-summary.json is stale; regenerate it")
            check_readme_counts(summary)
        else:
            OUTPUT.write_text(content, encoding="utf-8")
    except (KeyError, OSError, ValueError, json.JSONDecodeError) as exc:
        print(f"generate-catalog-summary: {exc}", file=sys.stderr)
        return 2
    print("Catalog summary is current." if args.check else "Generated catalog summary.")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

View on GitHub (pinned to a38d04c3d5)

Solutions

  1. Regenerate with the exact timestamp stored in the existing file: `python3 scripts/generate-catalog-summary.py --verified-at $(python3 -c "import json;print(json.load(open('catalog-summary.json'))['verifiedAt'])")`, then commit.
  2. If the data change is intentional and the verification date moved, regenerate with the new --verified-at and commit both files together.
  3. If only whitespace/line endings differ, normalize the file (LF endings, 2-space indent, trailing newline) by regenerating rather than hand-editing.
  4. Check for stray local CSV edits with `git status` before regenerating, so you do not commit a summary built from uncommitted data.

Example fix

# before (CI: catalog-summary.json is stale; regenerate it)
git pull  # CSV counts changed upstream

# after
python3 scripts/generate-catalog-summary.py --verified-at "$(python3 -c "import json;print(json.load(open('catalog-summary.json'))['verifiedAt'])")"
git add catalog-summary.json && git commit -m "chore: refresh catalog summary"
Defensive patterns

Strategy: validation

Validate before calling

# Regenerate into a temp string and diff before overwriting, in a wrapper script:
import json, pathlib, subprocess, sys
stored = pathlib.Path("catalog-summary.json")
expected = subprocess.run(
    [sys.executable, "scripts/generate-catalog-summary.py"], capture_output=True
)  # will fail loudly if flags missing
# safer: call build() directly and compare, so you see a diff instead of a boolean failure
import importlib.util
spec = importlib.util.spec_from_file_location("gcs", "scripts/generate-catalog-summary.py")
mod = importlib.util.module_from_spec(spec); spec.loader.exec_module(mod)
content = json.dumps(mod.build(stored_verified_at), ensure_ascii=False, indent=2) + "\n"
if stored.exists() and stored.read_text(encoding="utf-8") != content:
    print("diff:", [l for l in zip(stored.read_text().splitlines(), content.splitlines()) if l[0] != l[1]][:5])

Prevention

When it happens

Trigger: `--check` runs after CSV data files changed (counts/rows differ), or catalog-summary.json was regenerated with a different --verified-at than the one stored in its 'verifiedAt' field, or the file was reformatted (different indentation, key order, missing trailing newline, CRLF line endings from a Windows checkout).

Common situations: CI staleness check fails after a data PR touched src CSVs without regenerating the summary; a developer regenerated locally with today's date but the committed file carries an older timestamp; an editor or .gitattributes eol setting rewrote line endings.

Related errors


AI-assisted analysis of nextlevelbuilder/ui-ux-pro-max-skill@a38d04c3d5 (2026-08-14). Data as JSON: /api/errors/26fb69daeffc1f45. Report an issue: GitHub.