affaan-m/ECC · error · ValueError
insert requires an approved, resolved candidate
Error message
insert requires an approved, resolved candidate
What it means
_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.
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
Example fix
// before
inserts: [{candidate_id: "cand-9"}] // cand-9 review_status: "pending"
// after
// after approving:
inserts: [{candidate_id: "cand-9"}] // cand-9 review_status: "approved" Defensive patterns
Strategy: validation
Validate before calling
function assertInsertReferencesApproved(inserts, candidates) {
for (const ins of inserts) {
const c = candidates.find(c => c.id === ins.candidate_id);
if (!c || c.review_status !== "approved")
throw new Error(`insert references non-approved candidate ${ins.candidate_id}`);
}
} Try / catch
try {
buildApplicationBundle(cfg);
} catch (e) {
if (e.message.includes("insert requires an approved, resolved candidate")) {
cfg.inserts = cfg.inserts.filter(i =>
cfg.candidates.some(c => c.id === i.candidate_id && c.review_status === "approved"));
return buildApplicationBundle(cfg);
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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'.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- -32602
- a claim token is required
- a confirmed nonempty coordinate is required
- a generated candidate cannot claim original-source identity
- A managed install plan with operations is required.
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/9fa71ac438866d31.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/integration.py:316
evidence = _artifact(item["generation_receipt"], parse_json=True)
if not isinstance(evidence, dict) or not isinstance(evidence.get("request_id"), str):
raise ValueError("historical request evidence required")
_text(evidence["request_id"])
expected = {"source_sha256": source_hash, "compiled_input_sha256": input_hash,
"candidate_sha256": item["media"]["sha256"], "source_url": source_url}
if any(evidence.get(key) != value for key, value in expected.items()):
raise ValueError("historical evidence does not bind the candidate source/input/bytes")
result[name] = item
return result
def _inserts(items: list, candidates: dict, config: dict, input_hash: str, edit_hash: str) -> None:
occupied = []
for item in items:
_object(item, {"candidate_id", "candidate_range", "timeline_range", "retime", "approval_file"})
candidate = candidates.get(_text(item["candidate_id"]))
if candidate is None or candidate["review_status"] != "approved":
raise ValueError("insert requires an approved, resolved candidate")
target = _range(item["timeline_range"], config["baseline"]["timeline_range"])
source = _range(item["candidate_range"], [0, candidate["media_frames"]])
if any(_overlap(target, p["range"]) for p in config["protected_intervals"]):
raise ValueError("insert overlaps protected original stack")
if any(_overlap(target, span) for span in occupied):
raise ValueError("insert proposals overlap")
if (item["retime"] != "none" or target[1] - target[0] != source[1] - source[0]
or _rate(candidate["fps"]) != _rate(config["baseline"]["fps"])):
raise ValueError("candidate fps/duration/retime ambiguity")
evidence = _artifact(item["approval_file"], parse_json=True)
expected = {"status": "approved", "candidate_sha256": candidate["media"]["sha256"],
"source_sha256": config["source"]["media"]["sha256"],
"compiled_input_sha256": input_hash,
"edit_context_sha256": edit_hash,
"candidate_range": source, "timeline_range": target}
if not isinstance(evidence, dict) or any(
_canonical(evidence.get(key)) != _canonical(value) for key, value in expected.items()):
raise ValueError("approval evidence must bind exact source, candidate and placement")View on GitHub (pinned to 8321021c54)