calesthio/OpenMontage · error · CheckpointValidationError

Unknown or invalid style_playbook {style_playbook!r}. Availa

Error message

Unknown or invalid style_playbook {style_playbook!r}. Available playbooks: {available}. Underlying error: {exc}

What it means

The reference value started with "data:" but did not match the strict regex data:<mime>;base64,<base64chars>. Anything else — missing ";base64", URL-encoded payloads, whitespace inside the payload, plain-text data URIs, or commas/quotes in the base64 portion — is rejected up front.

Source

Thrown at lib/checkpoint.py:112

class CheckpointValidationError(ValueError):
    """Raised when a checkpoint or its canonical artifacts are invalid."""


def _validate_style_playbook(style_playbook: str | None) -> None:
    """Fail closed when a checkpoint names a visual identity that cannot load."""

    if style_playbook is None:
        return
    try:
        from styles.playbook_loader import list_playbooks, load_playbook

        load_playbook(style_playbook)
    except Exception as exc:
        try:
            available = list_playbooks()
        except Exception:
            available = []
        raise CheckpointValidationError(
            f"Unknown or invalid style_playbook {style_playbook!r}. "
            f"Available playbooks: {available}. Underlying error: {exc}"
        ) from exc


@lru_cache(maxsize=1)
def _load_checkpoint_schema() -> dict[str, Any]:
    with open(CHECKPOINT_SCHEMA_PATH, encoding="utf-8") as f:
        return json.load(f)


def _validate_artifacts_for_stage(
    stage: str,
    status: str,
    artifacts: dict[str, Any],
) -> None:
    # Valid stages come from the pipeline manifest (get_pipeline_stages), which
    # can declare stages beyond the 9 canonical ones (e.g. character-animation's

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Emit exactly data:<mime>;base64,<payload> with no extra parameters or whitespace.
  2. Strip whitespace/newlines from the payload before sending.
  3. Prefer passing a local file path or https URL and let the tool construct the data URI.

Example fix

# before
ref = "data:image/png;charset=utf-8;base64,iVBOR..."
# after
ref = "data:image/png;base64,iVBOR..."
Defensive patterns

Strategy: type-guard

Validate before calling

import re
DATA_URI_RE = re.compile(r"data:[a-z]+/[a-z0-9.+-]+;base64,[A-Za-z0-9+/=]+", re.IGNORECASE)
assert DATA_URI_RE.fullmatch(ref), "malformed data URI"

Type guard

def is_strict_data_uri(v: str) -> bool:
    import re
    return bool(re.fullmatch(r"data:[a-z]+/[a-z0-9.+-]+;base64,[A-Za-z0-9+/=]+", v, re.IGNORECASE))

Try / catch

try:
    tool.run(inputs)
except ValueError as e:
    if "strict base64 encoding" in str(e):
        rebuild_data_uri(ref)  # re-encode from source file with no extra params, retry
    else:
        raise

Prevention

When it happens

Trigger: Passing "data:image/png,url-encoded-bytes" (no base64 marker); a data URI containing newlines from JSON string wrapping; a truncated URI; MIME with unusual casing is fine (IGNORECASE) but parameters like ;charset=utf-8 before base64 break the match.

Common situations: Hand-building data URIs; LLMs emitting slightly malformed data URIs; HTML-sourced data URIs that include extra parameters; copy-paste truncation at a fixed column limit.

Related errors


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