affaan-m/ECC · error · ContractError

invalid or empty manifest

Error message

invalid or empty {modality} manifest

What it means

Each modality manifest must match its filename's modality and contain a non-empty 'requests' list. A manifest whose 'modality' field disagrees with the expected modality, or with no requests, raises this ContractError.

Solutions

  1. Set the manifest's 'modality' field to exactly the expected value matching the filename (e.g. 'image' for image.json).
  2. Populate 'requests' with at least one dry-run request entry.
  3. Regenerate the manifest via the tool rather than copying another modality's manifest.
  4. Validate the manifest JSON is complete (not truncated/empty) before running validation.

Example fix

// before
// video.json: {"modality": "image", "requests": []}
// after
// video.json: {"modality": "video", "requests": [{"dry_run": true, "submit": false, "provider_calls": 0, "provider_execution": false, "provider_call_mode": "disabled"}]}
Defensive patterns

Strategy: validation

Validate before calling

def manifest_ok(path, expected_modality):
    payload = json.loads(Path(path).read_text())
    return (payload.get("modality") == expected_modality
            and isinstance(payload.get("requests"), list)
            and len(payload["requests"]) > 0)

Type guard

def is_valid_manifest(payload: dict, modality: str) -> bool:
    reqs = payload.get("requests")
    return payload.get("modality") == modality and isinstance(reqs, list) and len(reqs) > 0

Try / catch

try:
    validate_manifests(manifests_dir)
except ContractError as e:
    if "invalid or empty" in str(e):
        regenerate_manifest_for(modality_from_message(e))
        validate_manifests(manifests_dir)
    else:
        raise

Prevention

When it happens

Trigger: image.json containing {"modality": "video", ...}; a manifest file that is valid JSON but an empty object {}; or {"modality": "image", "requests": []} passed through validate_manifests.

Common situations: Copying one manifest as a template for another without changing the 'modality' field; a generator crashing mid-write leaving an empty/partial JSON; requests filtered out upstream leaving an empty list; hand-editing that renamed the modality.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at skills/taste-application/scripts/tasteforge/contract.py:291

                raise ContractError(f"rule {rule.get('rule_id')} lacks time evidence")
            source_duration = item.get("source_duration")
            for time in times:
                _validate_media_time(
                    time, source_duration, label=f"rule {rule.get('rule_id')} time evidence"
                )


def validate_manifests(manifests_dir: str | Path) -> None:
    """Require image, video, and 3D-asset dry-run request manifests."""
    manifests_dir = Path(manifests_dir)
    found = {path.stem for path in manifests_dir.glob("*.json")} if manifests_dir.is_dir() else set()
    missing = _REQUIRED_MODALITIES - found
    if missing:
        raise ContractError(f"missing modality manifests: {sorted(missing)}")
    for modality in _REQUIRED_MODALITIES:
        payload = json.loads((manifests_dir / f"{modality}.json").read_text(encoding="utf-8"))
        if payload.get("modality") != modality or not payload.get("requests"):
            raise ContractError(f"invalid or empty {modality} manifest")
        if (payload.get("dry_run") is not True or payload.get("submit") is not False
                or type(payload.get("provider_calls")) is not int
                or payload.get("provider_calls") != 0
                or payload.get("provider_execution") is not False):
            raise ContractError(f"{modality} manifest crosses the dry-run boundary")
        for request in payload["requests"]:
            if (request.get("dry_run") is not True
                    or request.get("submit") is not False
                    or type(request.get("provider_calls")) is not int
                    or request.get("provider_calls") != 0
                    or request.get("provider_execution") is not False
                    or request.get("provider_call_mode") != "disabled"):
                raise ContractError(f"{modality} request crosses the dry-run boundary")


def validate_artifact_receipt(out_dir: str | Path, receipt: dict[str, Any]) -> None:
    """Verify that the receipt binds every emitted artifact and its provenance."""
    out_dir = Path(out_dir).resolve()

View on GitHub (pinned to 8321021c54)