calesthio/OpenMontage · error · CheckpointValidationError

Artifact {artifact_name!r} must be a JSON object matching it

Error message

Artifact {artifact_name!r} must be a JSON object matching its schema

What it means

base64.b64decode(..., validate=True) failed, meaning the payload contains characters outside the base64 alphabet (A–Z, a–z, 0–9, +, /, =) or malformed padding. The regex already restricts characters, so this mainly fires on wrong padding length or stray characters the regex's class permits but decode rejects (e.g. '=' in the middle).

Source

Thrown at lib/checkpoint.py:149

    # `character_design`/`rig_plan`, screen-demo's `real_capture`). Those have no
    # canonical artifact, so look it up defensively — a missing entry means the
    # stage simply has no required artifact, not a crash.
    required_artifact = CANONICAL_STAGE_ARTIFACTS.get(stage)
    if (
        required_artifact is not None
        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")

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Regenerate the base64 with standard padding from the source file.
  2. Validate locally first: base64.b64decode(payload, validate=True).
  3. Avoid hand-editing or splicing base64 strings; pass the file path and let the tool encode.

Example fix

# before
ref = "data:image/png;base64,iVBORw0KGgo=" + "extra"
# after
import base64
payload = base64.b64encode(open("ref.png", "rb").read()).decode("ascii")
ref = f"data:image/png;base64,{payload}"
Defensive patterns

Strategy: validation

Validate before calling

import base64, re
m = re.fullmatch(r"data:[^;]+;base64,(.+)", ref)
base64.b64decode(m.group(1), validate=True)  # raises here first if malformed

Try / catch

try:
    tool.run(inputs)
except ValueError as e:
    if "invalid base64" in str(e):
        regenerate_payload_from_file(ref)  # re-encode from the source asset, retry
    else:
        raise

Prevention

When it happens

Trigger: Payload with '=' padding in the interior; wrong number of padding characters; URL-safe base64 using '-'/'_' (those fail the regex first with error 329); a chunk lost or duplicated during string manipulation.

Common situations: Concatenating base64 fragments with a missing or extra segment; re-encoding bugs that strip or add padding; logs/tools that truncate at N characters.

Related errors


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