{"record":{"id":"9fa71ac438866d31","repo":"affaan-m/ECC","slug":"insert-requires-an-approved-resolved-candidate","errorCode":null,"errorMessage":"insert requires an approved, resolved candidate","messagePattern":"insert requires an approved, resolved candidate","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/integration.py","lineNumber":316,"sourceCode":"        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\"})\n        candidate = candidates.get(_text(item[\"candidate_id\"]))\n        if candidate is None or candidate[\"review_status\"] != \"approved\":\n            raise ValueError(\"insert requires an approved, resolved candidate\")\n        target = _range(item[\"timeline_range\"], config[\"baseline\"][\"timeline_range\"])\n        source = _range(item[\"candidate_range\"], [0, candidate[\"media_frames\"]])\n        if any(_overlap(target, p[\"range\"]) for p in config[\"protected_intervals\"]):\n            raise ValueError(\"insert overlaps protected original stack\")\n        if any(_overlap(target, span) for span in occupied):\n            raise ValueError(\"insert proposals overlap\")\n        if (item[\"retime\"] != \"none\" or target[1] - target[0] != source[1] - source[0]\n                or _rate(candidate[\"fps\"]) != _rate(config[\"baseline\"][\"fps\"])):\n            raise ValueError(\"candidate fps/duration/retime ambiguity\")\n        evidence = _artifact(item[\"approval_file\"], parse_json=True)\n        expected = {\"status\": \"approved\", \"candidate_sha256\": candidate[\"media\"][\"sha256\"],\n                    \"source_sha256\": config[\"source\"][\"media\"][\"sha256\"],\n                    \"compiled_input_sha256\": input_hash,\n                    \"edit_context_sha256\": edit_hash,\n                    \"candidate_range\": source, \"timeline_range\": target}\n        if not isinstance(evidence, dict) or any(\n                _canonical(evidence.get(key)) != _canonical(value) for key, value in expected.items()):\n            raise ValueError(\"approval evidence must bind exact source, candidate and placement\")","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/integration.py#L298-L334","documentation":"_inserts validates each insert proposal against the already-validated candidates dict. The referenced candidate must exist and its review_status must be 'approved' — pending or rejected candidates (or unknown ids) may not be inserted into the timeline. This enforces the human-approval gate at the insertion step.","triggerScenarios":"An insert item whose 'candidate_id' does not match any validated candidate (typo, or the candidate was dropped during validation due to a prior error), or whose candidate exists but review_status is 'pending' or 'rejected'.","commonSituations":"Review tool wrote 'pending' but the edit plan assumed approval; candidate ids renamed after the insert plan was drafted; the candidate failed earlier validation and was silently absent from the dict.","solutions":["Set the candidate's review_status to \"approved\" after human review before inserting","Fix the insert's candidate_id to reference an existing, validated candidate","Re-validate the candidates list first and resolve any candidates dropped by earlier errors, then re-run"],"exampleFix":"// before\ninserts: [{candidate_id: \"cand-9\"}]  // cand-9 review_status: \"pending\"\n// after\n// after approving:\ninserts: [{candidate_id: \"cand-9\"}]  // cand-9 review_status: \"approved\"","handlingStrategy":"validation","validationCode":"function assertInsertReferencesApproved(inserts, candidates) {\n  for (const ins of inserts) {\n    const c = candidates.find(c => c.id === ins.candidate_id);\n    if (!c || c.review_status !== \"approved\")\n      throw new Error(`insert references non-approved candidate ${ins.candidate_id}`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  buildApplicationBundle(cfg);\n} catch (e) {\n  if (e.message.includes(\"insert requires an approved, resolved candidate\")) {\n    cfg.inserts = cfg.inserts.filter(i =>\n      cfg.candidates.some(c => c.id === i.candidate_id && c.review_status === \"approved\"));\n    return buildApplicationBundle(cfg);\n  }\n  throw e;\n}","preventionTips":["Run the review step to completion before drafting insert proposals","Keep candidate ids stable between review and insert planning (no renaming)","Cross-check inserts against the validated candidate list in CI"],"tags":["approval-workflow","validation","inserts"],"backgroundTag":"invalid-state-transition","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"}