calesthio/OpenMontage · error · CheckpointValidationError

Artifact {artifact_name!r} failed schema validation: {exc}

Error message

Artifact {artifact_name!r} failed schema validation: {exc}

What it means

The base64 payload decoded successfully but the decoded byte count is >= max_bytes, so the tool refuses to inline it. This mirrors the local-file size cap but measures the actual decoded media size rather than the file on disk (base64 inflates ~33%, so both checks use the decoded size consistently).

Source

Thrown at lib/checkpoint.py:155

        and status in {"completed", "awaiting_human"}
        and required_artifact not in artifacts
    ):
        raise CheckpointValidationError(
            f"Stage {stage!r} with status {status!r} must include "
            f"canonical artifact {required_artifact!r}"
        )

    for artifact_name, artifact_data in artifacts.items():
        if artifact_name not in ARTIFACT_NAMES:
            continue
        if not isinstance(artifact_data, dict):
            raise CheckpointValidationError(
                f"Artifact {artifact_name!r} must be a JSON object matching its schema"
            )
        try:
            validate_artifact(artifact_name, artifact_data)
        except Exception as exc:
            raise CheckpointValidationError(
                f"Artifact {artifact_name!r} failed schema validation: {exc}"
            ) from exc


def validate_checkpoint(checkpoint: dict[str, Any]) -> None:
    """Validate checkpoint structure and canonical artifact payloads.

    Uses pipeline_type (if present) to resolve the valid stage list.
    Falls back to ALL_KNOWN_STAGES when pipeline_type is absent.
    """
    stage = checkpoint.get("stage")
    status = checkpoint.get("status")
    artifacts = checkpoint.get("artifacts")
    pipeline_type = checkpoint.get("pipeline_type")

    valid_stages = (
        set(get_pipeline_stages(pipeline_type)) if pipeline_type
        else ALL_KNOWN_STAGES

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Compress the media (JPEG q85, AAC/MP3 audio) before base64-encoding.
  2. Host the asset at a public https URL and pass the URL instead of a data URI.
  3. Split very long audio references into separate <=15s clips within the size cap.

Example fix

# before
ref = "data:audio/wav;base64," + b64(wav_20mb)
# after
# run: ffmpeg -i in.wav -b:a 128k in.mp3
ref = "https://cdn.example.com/in.mp3"
Defensive patterns

Strategy: validation

Validate before calling

import base64
size = len(base64.b64decode(payload, validate=True))
assert size < MAX_BYTES, f"decoded {size} bytes exceeds cap"

Try / catch

try:
    tool.run(inputs)
except ValueError as e:
    if "must be smaller than" in str(e):
        switch_to_https_url(ref)  # host the asset, pass URL, retry
    else:
        raise

Prevention

When it happens

Trigger: Inlining a 20MB WAV as a data:audio URI; a data URI for a large TIFF/PNG photo exceeding the MB cap shown in the message.

Common situations: Client-side previews exported as lossless PNG data URIs; uncompressed audio pasted inline; treating data URIs as a way to dodge the local-file size check (they are not — decoded size is checked).

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/6ae7b42a595586e4. Report an issue: GitHub.