calesthio/OpenMontage · error · CheckpointValidationError

Checkpoint artifacts must be a dictionary

Error message

Checkpoint artifacts must be a dictionary

What it means

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.

Source

Thrown at lib/checkpoint.py:184

    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
    )

    if not isinstance(stage, str) or stage not in valid_stages:
        raise CheckpointValidationError(
            f"Invalid stage: {stage!r} for pipeline {pipeline_type!r}. "
            f"Valid stages: {sorted(valid_stages)}"
        )
    if not isinstance(status, str):
        raise CheckpointValidationError(f"Invalid status: {status!r}")
    if not isinstance(artifacts, dict):
        raise CheckpointValidationError("Checkpoint artifacts must be a dictionary")

    _validate_artifacts_for_stage(stage, status, artifacts)

    try:
        jsonschema.validate(instance=checkpoint, schema=_load_checkpoint_schema())
    except jsonschema.ValidationError as exc:
        raise CheckpointValidationError(f"Checkpoint failed schema validation: {exc.message}") from exc


def _checkpoint_path(pipeline_dir: Path, project_id: str, stage: str) -> Path:
    return pipeline_dir / project_id / f"checkpoint_{stage}.json"


def init_project(
    project_id: str,
    *,
    title: str,
    pipeline_type: str,

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. 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.
  2. Re-encode suspect audio with ffmpeg to a clean container.
  3. Check exec permissions and container security policies for spawning subprocesses.

Example fix

# before
inputs = {"audio_url_local": "sketchy_download.mp3"}
# after
# run: ffmpeg -y -i sketchy_download.mp3 -t 10 -b:a 128k clean.mp3
inputs = {"audio_url_local": "clean.mp3"}
Defensive patterns

Strategy: fallback

Validate before calling

import subprocess
r = subprocess.run(["ffprobe", "-v", "error", "-show_entries", "format=duration",
                    "-of", "default=noprint_wrappers=1:nokey=1", ref],
                   capture_output=True, text=True, timeout=10)
assert r.returncode == 0 and float(r.stdout.strip()) > 0

Try / catch

try:
    tool.run(inputs)
except ValueError as e:
    if "failed to probe" in str(e):
        reencode_audio(ref)  # ffmpeg re-mux to a clean file, then retry once
    else:
        raise

Prevention

When it happens

Trigger: 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).

Common situations: 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).

Related errors


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