affaan-m/ECC · error · ValueError

candidate is bound to a different source or input

Error message

candidate is bound to a different source or input

What it means

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.

Solutions

  1. Regenerate the candidates against the current source and compiled input so their recorded hashes match
  2. 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
  3. If the source media legitimately changed, re-run the generation pipeline end-to-end instead of reusing old candidates

Example fix

// before
candidate.source_sha256 = "abc123"  # old source
build(source_hash="def456", ...)
// after
candidate.source_sha256 = "def456"  # regenerated against current source
build(source_hash="def456", ...)
Defensive patterns

Strategy: validation

Validate before calling

function assertCandidateBinding(c, sourceHash, inputHash) {
  if (c.source_sha256 !== sourceHash || c.compiled_input_sha256 !== inputHash)
    throw new Error(`candidate ${c.id} bound to a different run`);
}

Try / catch

try {
  buildApplicationBundle(cfg);
} catch (e) {
  if (e.message.includes("bound to a different source or input")) {
    cfg.candidates = await regenerateCandidates(cfg.source, cfg.compiledInput);
    return buildApplicationBundle(cfg);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/5da312a8579af917. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/tasteforge/integration.py:295

            for track, clips in sorted(tracks.items()) for index, clip in enumerate(clips)
            if any(_overlap(p["range"], [clip["start"], clip["end"]]) for p in protected)]


def _candidates(items: list, source_hash: str, input_hash: str, source_url: str) -> dict:
    result = {}
    for item in items:
        _object(item, {"id", "media", "media_frames", "fps", "origin", "relationship",
                       "source_sha256", "compiled_input_sha256", "review_status", "generation_receipt"})
        name = _text(item["id"])
        if name in result:
            raise ValueError("candidate ids must be unique")
        _artifact(item["media"])
        _integer(item["media_frames"], 1)
        _rate(item["fps"])
        if item["origin"] != "provider_generated" or item["relationship"] != "generated_variation":
            raise ValueError("a generated candidate cannot claim original-source identity")
        if item["source_sha256"] != source_hash or item["compiled_input_sha256"] != input_hash:
            raise ValueError("candidate is bound to a different source or input")
        if item["review_status"] not in ("pending", "rejected", "approved"):
            raise ValueError("explicit candidate review state required")
        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"})

View on GitHub (pinned to 8321021c54)