{"record":{"id":"5da312a8579af917","repo":"affaan-m/ECC","slug":"candidate-is-bound-to-a-different-source-or-input","errorCode":null,"errorMessage":"candidate is bound to a different source or input","messagePattern":"candidate is bound to a different source or input","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/integration.py","lineNumber":295,"sourceCode":"            for track, clips in sorted(tracks.items()) for index, clip in enumerate(clips)\n            if any(_overlap(p[\"range\"], [clip[\"start\"], clip[\"end\"]]) for p in protected)]\n\n\ndef _candidates(items: list, source_hash: str, input_hash: str, source_url: str) -> dict:\n    result = {}\n    for item in items:\n        _object(item, {\"id\", \"media\", \"media_frames\", \"fps\", \"origin\", \"relationship\",\n                       \"source_sha256\", \"compiled_input_sha256\", \"review_status\", \"generation_receipt\"})\n        name = _text(item[\"id\"])\n        if name in result:\n            raise ValueError(\"candidate ids must be unique\")\n        _artifact(item[\"media\"])\n        _integer(item[\"media_frames\"], 1)\n        _rate(item[\"fps\"])\n        if item[\"origin\"] != \"provider_generated\" or item[\"relationship\"] != \"generated_variation\":\n            raise ValueError(\"a generated candidate cannot claim original-source identity\")\n        if item[\"source_sha256\"] != source_hash or item[\"compiled_input_sha256\"] != input_hash:\n            raise ValueError(\"candidate is bound to a different source or input\")\n        if item[\"review_status\"] not in (\"pending\", \"rejected\", \"approved\"):\n            raise ValueError(\"explicit candidate review state required\")\n        evidence = _artifact(item[\"generation_receipt\"], parse_json=True)\n        if not isinstance(evidence, dict) or not isinstance(evidence.get(\"request_id\"), str):\n            raise ValueError(\"historical request evidence required\")\n        _text(evidence[\"request_id\"])\n        expected = {\"source_sha256\": source_hash, \"compiled_input_sha256\": input_hash,\n                    \"candidate_sha256\": item[\"media\"][\"sha256\"], \"source_url\": source_url}\n        if any(evidence.get(key) != value for key, value in expected.items()):\n            raise ValueError(\"historical evidence does not bind the candidate source/input/bytes\")\n        result[name] = item\n    return result\n\n\ndef _inserts(items: list, candidates: dict, config: dict, input_hash: str, edit_hash: str) -> None:\n    occupied = []\n    for item in items:\n        _object(item, {\"candidate_id\", \"candidate_range\", \"timeline_range\", \"retime\", \"approval_file\"})","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/integration.py#L277-L313","documentation":"Each candidate must cryptographically bind to the exact run: its 'source_sha256' must equal the bundle's source hash and 'compiled_input_sha256' must equal the compiled-input hash passed to build_application_bundle. If either hash differs, the candidate was generated against a different source video or a different compiled prompt/input, and TasteForge refuses to mix it in.","triggerScenarios":"Reusing candidate artifacts from an earlier compile of the source video (source changed since generation), or from a run with a different edited input/prompt (compiled_input_sha256 mismatch). Also occurs when hashes are recomputed after normalizing media before generation.","commonSituations":"Iterating on the edit/input after generating candidates and forgetting to regenerate them; regenerating the source at a different resolution or trim; copying candidate JSON between project folders.","solutions":["Regenerate the candidates against the current source and compiled input so their recorded hashes match","Ensure the source_sha256 and compiled_input_sha256 used when calling build_application_bundle are identical to those recorded in each candidate's generation receipt","If the source media legitimately changed, re-run the generation pipeline end-to-end instead of reusing old candidates"],"exampleFix":"// before\ncandidate.source_sha256 = \"abc123\"  # old source\nbuild(source_hash=\"def456\", ...)\n// after\ncandidate.source_sha256 = \"def456\"  # regenerated against current source\nbuild(source_hash=\"def456\", ...)","handlingStrategy":"validation","validationCode":"function assertCandidateBinding(c, sourceHash, inputHash) {\n  if (c.source_sha256 !== sourceHash || c.compiled_input_sha256 !== inputHash)\n    throw new Error(`candidate ${c.id} bound to a different run`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  buildApplicationBundle(cfg);\n} catch (e) {\n  if (e.message.includes(\"bound to a different source or input\")) {\n    cfg.candidates = await regenerateCandidates(cfg.source, cfg.compiledInput);\n    return buildApplicationBundle(cfg);\n  }\n  throw e;\n}","preventionTips":["Regenerate candidates whenever the source or compiled input changes — never reuse across runs","Store source_sha256/compiled_input_sha256 alongside candidates and compare before building","Hash the final normalized source once and pass that same value everywhere"],"tags":["integrity","provenance","hash-mismatch"],"backgroundTag":"checksum-mismatch","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"}