affaan-m/ECC · error · ValueError
invalid JSON artifact
Error message
invalid JSON artifact
What it means
_load_json wraps json.loads and a canonicalization pass; if parsing raises UnicodeError (invalid UTF-8/escape sequences) or RecursionError (nesting beyond the interpreter limit), it re-raises as "invalid JSON artifact". It signals bytes that cannot be decoded as safe, bounded JSON.
Solutions
- Re-encode the file as UTF-8 without BOM (`iconv -f UTF-16 -t UTF-8 in.json > out.json`).
- Validate the file with `python -m json.tool file.json` to see the exact decode error.
- Check for accidental binary content (`file snapshot.json` should say 'JSON' or 'ASCII text').
- Flatten or split pathologically nested JSON (depth > ~1000) before loading.
Example fix
// before $ file snapshot.json -> data (UTF-16) // after $ iconv -f UTF-16LE -t UTF-8 snapshot.json > snapshot.utf8.json
Defensive patterns
Strategy: validation
Validate before calling
def check_decodable(path):
raw = open(path, "rb").read()
try:
raw.decode("utf-8")
except UnicodeDecodeError as e:
raise ValueError(f"{path}: not UTF-8: {e}") Try / catch
try:
request = load_application_request(path)
except ValueError as exc:
if "invalid JSON artifact" in str(exc):
print(f"{path}: re-encode as UTF-8 and validate with python -m json.tool")
raise Prevention
- Save/export all JSON as UTF-8 without BOM.
- Run `python -m json.tool` on generated artifacts before use.
- Never rename binary files to .json.
- Keep JSON nesting shallow (< a few hundred levels).
When it happens
Trigger: Calling load_application_request or any _artifact(..., parse_json=True) path where the file contains invalid UTF-8 bytes, malformed \u escapes, or JSON nested deeper than Python's recursion limit (~1000 levels).
Common situations: Files saved with a non-UTF-8 encoding (UTF-16, Latin-1); binary files accidentally given a .json extension; truncated downloads; machine-generated deeply nested JSON.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid
- application request must be a JSON object
- approved text must be valid UTF-8 text
- bundle values must be finite JSON data
- candidate configuration exceeds 1 MiB
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/84a5fb7e13575a13.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/integration.py:184
raise ValueError("application request must be a JSON object")
return value
def _load_json(data: bytes) -> Any:
def unique(pairs):
result = {}
for key, value in pairs:
if key in result:
raise ValueError("duplicate JSON field")
result[key] = value
return result
try:
value = json.loads(data, object_pairs_hook=unique)
_canonical(value)
return value
except (UnicodeError, RecursionError) as exc:
raise ValueError("invalid JSON artifact") from exc
def _snapshot(baseline: dict) -> dict:
_object(baseline, {"project_file", "snapshot_file", "project_name", "timeline_name",
"fps", "timeline_range"})
_rate(baseline["fps"])
bounds = _range(baseline["timeline_range"])
_artifact(baseline["project_file"])
snapshot = _artifact(baseline["snapshot_file"], parse_json=True)
if not isinstance(snapshot, dict):
raise ValueError("native snapshot must be an object")
settings = snapshot.get("settings")
native_fps = settings.get("timelineFrameRate") if isinstance(settings, dict) else None
# Resolve's conventional decimal NTSC labels represent these exact rates.
ntsc = {"23.976": "24000/1001", "29.97": "30000/1001", "59.94": "60000/1001"}
try:
if type(native_fps) not in (str, int, float):
raise ValueError("native fps missing")View on GitHub (pinned to 8321021c54)