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
- Send one of the supported values exactly: "image", "text", or "video".
- Validate and reject unknown inputMode at the route boundary (return 400) before it reaches the builder.
- If adding a new mode, implement its branch in build_create_prompt_from_input and widen the InputMode Literal in the same change.
- 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
- Validate inputMode against the Literal at the API boundary and 400 on unknowns
- Add the backend branch in the same commit that widens the InputMode Literal
- Pin frontend and backend versions together when introducing new modes
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
- Video mode requires a video to be provided
- Update requests require history or fileState.content
- Update history must include at least one user message
- Invalid input mode: {input_mode}
- --iou-threshold must be between 0 and 1
AI-assisted analysis of abi/screenshot-to-code@d026163f58 (2026-08-14).
Data as JSON: /api/errors/acd831ca3eb5990b.
Report an issue: GitHub.