{"record":{"id":"fccc86205de353bf","repo":"affaan-m/ECC","slug":"bundle-values-must-be-finite-json-data","errorCode":null,"errorMessage":"bundle values must be finite JSON data","messagePattern":"bundle values must be finite JSON data","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/integration.py","lineNumber":32,"sourceCode":"import os\nimport re\nimport stat\nfrom fractions import Fraction\nfrom pathlib import Path\nfrom typing import Any\nfrom urllib.parse import urlsplit\n\n\n_REQUIRED = {\"baseline\", \"source\", \"audio\", \"protected_intervals\"}\n_OPTIONAL = {\"candidates\", \"inserts\", \"historical_receipts\"}\n_MAX_JSON = 8 * 1024 * 1024\n\n\ndef _canonical(value: Any) -> bytes:\n    try:\n        return json.dumps(value, sort_keys=True, separators=(\",\", \":\"), allow_nan=False).encode()\n    except (TypeError, ValueError, RecursionError) as exc:\n        raise ValueError(\"bundle values must be finite JSON data\") from exc\n\n\ndef _digest(value: Any) -> str:\n    return hashlib.sha256(_canonical(value)).hexdigest()\n\n\ndef _object(value: Any, required: set[str], optional: set[str] | None = None) -> dict:\n    if not isinstance(value, dict) or not required <= value.keys():\n        raise ValueError(\"missing required bundle fields\")\n    if value.keys() - required - (optional or set()):\n        raise ValueError(\"unknown bundle fields\")\n    return value\n\n\ndef _text(value: Any) -> str:\n    if not isinstance(value, str) or not value.strip():\n        raise ValueError(\"nonempty text required\")\n    return value","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/integration.py#L14-L50","documentation":"_canonical serializes a bundle value to canonical JSON for hashing/digesting, using allow_nan=False. Any value that is not finite JSON data (sets, datetime, NaN/Infinity floats, cyclic structures) raises ValueError. This guarantees bundle digests are reproducible.","triggerScenarios":"Passing non-JSON-serializable values into build_application_bundle or validate_application_bundle (e.g. a Python set, datetime, Decimal, float('nan'), float('inf'), or a self-referencing dict).","commonSituations":"Loading snapshots from a non-JSON source (yaml/DB) without converting types, hand-constructing bundle dicts with float('nan') for unknown fps, or leaving numpy scalar types in parsed data.","solutions":["Convert non-JSON types to JSON-compatible ones (sets->lists, datetime->ISO strings, numpy scalars->int/float)","Replace NaN/Infinity floats with None or explicit sentinel values before building the bundle","Catch this error and dump repr(value) of bundle parts to locate the offending field"],"exampleFix":"// before\nbundle = {\"snapshot\": {..., \"captured_at\": datetime.now()}}\n// after\nbundle = {\"snapshot\": {..., \"captured_at\": datetime.now().isoformat()}}","handlingStrategy":"validation","validationCode":"def ensure_json_finite(value):\n    json.dumps(value, allow_nan=False)  # raises before build if not serializable","typeGuard":null,"tryCatchPattern":"try:\n    bundle = build_application_bundle(data)\nexcept ValueError as e:\n    if \"finite JSON\" in str(e):\n        print(\"bundle contains non-JSON or non-finite values; inspect repr(data)\")\n    else:\n        raise","preventionTips":["Convert sets/datetimes/numpy types to JSON-native equivalents before bundling","Never use float('nan')/float('inf') in bundle data; use None or sentinels","Run a trial json.dumps(value, allow_nan=False) smoke test on generated bundles"],"tags":["json","serialization","validation"],"backgroundTag":"json-serialization-failed","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}