{"record":{"id":"88a3d7a9afa1d600","repo":"calesthio/OpenMontage","slug":"checkpoint-artifacts-must-be-a-dictionary","errorCode":null,"errorMessage":"Checkpoint artifacts must be a dictionary","messagePattern":"Checkpoint artifacts must be a dictionary","errorType":"validation","errorClass":"CheckpointValidationError","httpStatus":null,"severity":"error","filePath":"lib/checkpoint.py","lineNumber":184,"sourceCode":"    stage = checkpoint.get(\"stage\")\n    status = checkpoint.get(\"status\")\n    artifacts = checkpoint.get(\"artifacts\")\n    pipeline_type = checkpoint.get(\"pipeline_type\")\n\n    valid_stages = (\n        set(get_pipeline_stages(pipeline_type)) if pipeline_type\n        else ALL_KNOWN_STAGES\n    )\n\n    if not isinstance(stage, str) or stage not in valid_stages:\n        raise CheckpointValidationError(\n            f\"Invalid stage: {stage!r} for pipeline {pipeline_type!r}. \"\n            f\"Valid stages: {sorted(valid_stages)}\"\n        )\n    if not isinstance(status, str):\n        raise CheckpointValidationError(f\"Invalid status: {status!r}\")\n    if not isinstance(artifacts, dict):\n        raise CheckpointValidationError(\"Checkpoint artifacts must be a dictionary\")\n\n    _validate_artifacts_for_stage(stage, status, artifacts)\n\n    try:\n        jsonschema.validate(instance=checkpoint, schema=_load_checkpoint_schema())\n    except jsonschema.ValidationError as exc:\n        raise CheckpointValidationError(f\"Checkpoint failed schema validation: {exc.message}\") from exc\n\n\ndef _checkpoint_path(pipeline_dir: Path, project_id: str, stage: str) -> Path:\n    return pipeline_dir / project_id / f\"checkpoint_{stage}.json\"\n\n\ndef init_project(\n    project_id: str,\n    *,\n    title: str,\n    pipeline_type: str,","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/lib/checkpoint.py#L166-L202","documentation":"Running ffprobe raised OSError, ValueError, or subprocess.SubprocessError — the binary could not be executed, timed out (10s), or its output could not be parsed as a float. The tool deliberately converts all probe infrastructure failures into this ValueError rather than leaking subprocess errors.","triggerScenarios":"ffprobe hangs on a pathological/corrupt media file and hits the 10s timeout; ffprobe exists but is a broken executable or lacks exec permission; stdout empty or non-numeric (returncode==0 with no duration line is handled by the range check, but float() raising ValueError on odd output lands here).","commonSituations":"Truncated/corrupt audio files that make ffprobe stall; container seccomp blocking subprocess spawn; resource-starved runners where ffprobe is OOM-killed (raises via SubprocessError/OSError).","solutions":["Test the file directly: ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 your.mp3 — if it hangs, re-encode or replace the file.","Re-encode suspect audio with ffmpeg to a clean container.","Check exec permissions and container security policies for spawning subprocesses."],"exampleFix":"# before\ninputs = {\"audio_url_local\": \"sketchy_download.mp3\"}\n# after\n# run: ffmpeg -y -i sketchy_download.mp3 -t 10 -b:a 128k clean.mp3\ninputs = {\"audio_url_local\": \"clean.mp3\"}","handlingStrategy":"fallback","validationCode":"import subprocess\nr = subprocess.run([\"ffprobe\", \"-v\", \"error\", \"-show_entries\", \"format=duration\",\n                    \"-of\", \"default=noprint_wrappers=1:nokey=1\", ref],\n                   capture_output=True, text=True, timeout=10)\nassert r.returncode == 0 and float(r.stdout.strip()) > 0","typeGuard":null,"tryCatchPattern":"try:\n    tool.run(inputs)\nexcept ValueError as e:\n    if \"failed to probe\" in str(e):\n        reencode_audio(ref)  # ffmpeg re-mux to a clean file, then retry once\n    else:\n        raise","preventionTips":["Re-encode downloaded/converted audio once at ingest so ffprobe never sees broken files.","Keep an ffmpeg install healthy in the runtime image (broken symlinks cause exec failures)."],"tags":["python","ffmpeg","ffprobe","timeout","subprocess","audio","seedance"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}