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
- 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.
- If the data change is intentional and the verification date moved, regenerate with the new --verified-at and commit both files together.
- If only whitespace/line endings differ, normalize the file (LF endings, 2-space indent, trailing newline) by regenerating rather than hand-editing.
- 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
- Run `generate-catalog-summary.py --check` locally before every commit that touches data CSVs.
- Add the --check run to CI so stale summaries block merge instead of surprising you later.
- Never hand-format catalog-summary.json; always regenerate so indentation and trailing newline match exactly.
- Use LF line endings (.gitattributes: *.json text eol=lf) to avoid false staleness on Windows checkouts.
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
- Invalid JSON file {path}: {error}
- Invalid threshold manifest:\n- {manifest_errors}
- Relevance gate failed:\n- {failures}
- verified-at has suspicious date {value!r}
- {name} catalog counts are stale: {', '.join(missing)}
AI-assisted analysis of nextlevelbuilder/ui-ux-pro-max-skill@a38d04c3d5 (2026-08-14).
Data as JSON: /api/errors/26fb69daeffc1f45.
Report an issue: GitHub.