affaan-m/ECC · error · ValueError

historical request evidence required

Error message

historical request evidence required

What it means

Each candidate must include a 'generation_receipt' artifact that parses as JSON and contains a string 'request_id'. This receipt is the historical evidence tying the candidate to an actual provider generation request; without it TasteForge cannot audit where the footage came from and raises this error.

Solutions

  1. Attach the original provider generation receipt JSON (with a string request_id) to each candidate
  2. Re-export the candidate from the generation pipeline so the receipt is included and well-formed
  3. Validate the receipt parses as a JSON object with a non-empty request_id before calling build_application_bundle

Example fix

// before
{"id": "cand-2", "generation_receipt": {"ts": 123}}
// after
{"id": "cand-2", "generation_receipt": {"request_id": "req_9f3a", "ts": 123}}
Defensive patterns

Strategy: validation

Validate before calling

function assertReceipt(c) {
  const r = c.generation_receipt;
  if (typeof r !== "object" || r === null || typeof r.request_id !== "string" || !r.request_id)
    throw new Error(`candidate ${c.id} lacks valid generation receipt`);
}

Type guard

function hasValidReceipt(c) {
  const r = c?.generation_receipt;
  return typeof r === "object" && r !== null && typeof r.request_id === "string";
}

Try / catch

try {
  buildApplicationBundle(cfg);
} catch (e) {
  if (e.message.includes("historical request evidence required")) {
    await attachReceipts(cfg.candidates); // fetch from generation store by media hash
    return buildApplicationBundle(cfg);
  }
  throw e;
}

Prevention

When it happens

Trigger: Omitting the generation_receipt field, passing a non-JSON artifact path, or providing a receipt JSON whose top level is not an object or lacks a string 'request_id'.

Common situations: Hand-building candidates without running the provider (synthetic/test entries); receipts saved in a legacy format without request_id; receipt files truncated or corrupted on disk.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

    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"})
        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"]])

View on GitHub (pinned to 8321021c54)