{"record":{"id":"543e0c03e0f2e3bf","repo":"calesthio/OpenMontage","slug":"artifact-artifact-name-r-must-be-a-json-object-m","errorCode":null,"errorMessage":"Artifact {artifact_name!r} must be a JSON object matching its schema","messagePattern":"Artifact (.+?) must be a JSON object matching its schema","errorType":"validation","errorClass":"CheckpointValidationError","httpStatus":null,"severity":"error","filePath":"lib/checkpoint.py","lineNumber":149,"sourceCode":"    # `character_design`/`rig_plan`, screen-demo's `real_capture`). Those have no\n    # canonical artifact, so look it up defensively — a missing entry means the\n    # stage simply has no required artifact, not a crash.\n    required_artifact = CANONICAL_STAGE_ARTIFACTS.get(stage)\n    if (\n        required_artifact is not None\n        and status in {\"completed\", \"awaiting_human\"}\n        and required_artifact not in artifacts\n    ):\n        raise CheckpointValidationError(\n            f\"Stage {stage!r} with status {status!r} must include \"\n            f\"canonical artifact {required_artifact!r}\"\n        )\n\n    for artifact_name, artifact_data in artifacts.items():\n        if artifact_name not in ARTIFACT_NAMES:\n            continue\n        if not isinstance(artifact_data, dict):\n            raise CheckpointValidationError(\n                f\"Artifact {artifact_name!r} must be a JSON object matching its schema\"\n            )\n        try:\n            validate_artifact(artifact_name, artifact_data)\n        except Exception as exc:\n            raise CheckpointValidationError(\n                f\"Artifact {artifact_name!r} failed schema validation: {exc}\"\n            ) from exc\n\n\ndef validate_checkpoint(checkpoint: dict[str, Any]) -> None:\n    \"\"\"Validate checkpoint structure and canonical artifact payloads.\n\n    Uses pipeline_type (if present) to resolve the valid stage list.\n    Falls back to ALL_KNOWN_STAGES when pipeline_type is absent.\n    \"\"\"\n    stage = checkpoint.get(\"stage\")\n    status = checkpoint.get(\"status\")","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/lib/checkpoint.py#L131-L167","documentation":"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).","triggerScenarios":"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.","commonSituations":"Concatenating base64 fragments with a missing or extra segment; re-encoding bugs that strip or add padding; logs/tools that truncate at N characters.","solutions":["Regenerate the base64 with standard padding from the source file.","Validate locally first: base64.b64decode(payload, validate=True).","Avoid hand-editing or splicing base64 strings; pass the file path and let the tool encode."],"exampleFix":"# before\nref = \"data:image/png;base64,iVBORw0KGgo=\" + \"extra\"\n# after\nimport base64\npayload = base64.b64encode(open(\"ref.png\", \"rb\").read()).decode(\"ascii\")\nref = f\"data:image/png;base64,{payload}\"","handlingStrategy":"validation","validationCode":"import base64, re\nm = re.fullmatch(r\"data:[^;]+;base64,(.+)\", ref)\nbase64.b64decode(m.group(1), validate=True)  # raises here first if malformed","typeGuard":null,"tryCatchPattern":"try:\n    tool.run(inputs)\nexcept ValueError as e:\n    if \"invalid base64\" in str(e):\n        regenerate_payload_from_file(ref)  # re-encode from the source asset, retry\n    else:\n        raise","preventionTips":["Never splice or truncate base64 payloads; regenerate them from source bytes.","Keep payloads as single-line ASCII strings through every serialization hop."],"tags":["python","validation","base64","data-uri","seedance"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}