abi/screenshot-to-code · error · ValueError

Unsupported input mode: {input_mode}

Error message

Unsupported input mode: {input_mode}

What it means

Raised at the bottom of build_create_prompt_from_input when input_mode is none of "image", "text", or "video" — the only three branches the builder implements. The Literal InputMode type promises one of those values, so hitting this means an untyped/improperly validated value reached a typed boundary (the value is echoed in the message).

Source

Thrown at backend/prompts/create/__init__.py:45

        return build_text_prompt_messages(
            text_prompt=prompt["text"],
            stack=stack,
            image_generation_enabled=image_generation_enabled,
            design_system=design_system,
        )
    if input_mode == "video":
        video_urls = prompt.get("videos", [])
        if not video_urls:
            raise ValueError("Video mode requires a video to be provided")
        video_url = video_urls[0]
        return build_video_prompt_messages(
            video_data_url=video_url,
            stack=stack,
            text_prompt=prompt.get("text", ""),
            image_generation_enabled=image_generation_enabled,
            design_system=design_system,
        )
    raise ValueError(f"Unsupported input mode: {input_mode}")


__all__ = ["build_create_prompt_from_input"]

View on GitHub (pinned to d026163f58)

Solutions

  1. Send one of the supported values exactly: "image", "text", or "video".
  2. Validate and reject unknown inputMode at the route boundary (return 400) before it reaches the builder.
  3. If adding a new mode, implement its branch in build_create_prompt_from_input and widen the InputMode Literal in the same change.
  4. Check frontend/backend versions are in sync when a new mode is involved.

Example fix

# before
build_create_prompt_from_input(prompt, input_mode="audio", stack=stack)

# after — supported mode
build_create_prompt_from_input(prompt, input_mode="video", stack=stack)
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_INPUT_MODES = {"image", "text", "video"}

def is_supported_input_mode(mode: str) -> bool:
    return mode in SUPPORTED_INPUT_MODES

Type guard

from typing import Literal

InputModeT = Literal["image", "video", "text"]

def is_input_mode(value: object) -> TypeGuard[InputModeT]:
    return isinstance(value, str) and value in ("image", "video", "text")

Try / catch

try:
    messages = build_create_prompt_from_input(prompt, input_mode, stack)
except ValueError as e:
    if str(e).startswith("Unsupported input mode"):
        return error_response(f"inputMode must be image|text|video, got {input_mode!r}", 400)
    raise

Prevention

When it happens

Trigger: Calling the builder with input_mode="audio", "", None, or a differently-cased "Image". In the live app: the WebSocket route passing raw JSON inputMode from the client straight through without narrowing, or a new mode added to the frontend before backend support.

Common situations: Frontend/backend version skew after adding a new input mode; hand-rolled API clients sending arbitrary strings; typo or casing mismatch in the payload field.

Related errors


AI-assisted analysis of abi/screenshot-to-code@d026163f58 (2026-08-14). Data as JSON: /api/errors/acd831ca3eb5990b. Report an issue: GitHub.