abi/screenshot-to-code · error · ValueError

Prompt item {index} must be a string or object.

Error message

Prompt item {index} must be a string or object.

What it means

ValueError("Prompt item {index} must be a string or object.") raised by load_prompts() when an element of the prompt array is neither a str nor a dict — i.e. a JSON number, boolean, or null. The 1-based index in the message identifies the offending element. It aborts the eval run at load time.

Source

Thrown at backend/run_image_generation_evals.py:78

def load_prompts(prompt_file: Path) -> list[PromptItem]:
    raw: Any = json.loads(prompt_file.read_text())
    if not isinstance(raw, list):
        raise ValueError("Prompt file must contain a JSON array.")

    prompts: list[PromptItem] = []
    for index, item in enumerate(cast(list[Any], raw), start=1):
        if isinstance(item, str):
            prompts.append(
                {
                    "id": f"{index:03d}",
                    "category": "Prompt",
                    "prompt": item,
                }
            )
            continue

        if not isinstance(item, dict):
            raise ValueError(f"Prompt item {index} must be a string or object.")

        item_dict = cast(dict[str, Any], item)
        prompt = item_dict.get("prompt")
        if not isinstance(prompt, str) or not prompt.strip():
            raise ValueError(f"Prompt item {index} is missing a prompt string.")

        prompt_id = item_dict.get("id")
        category = item_dict.get("category")
        prompts.append(
            {
                "id": prompt_id if isinstance(prompt_id, str) else f"{index:03d}",
                "category": category if isinstance(category, str) else "Prompt",
                "prompt": prompt,
            }
        )

    return prompts

View on GitHub (pinned to d026163f58)

Solutions

  1. Open the prompt file, jump to the reported 1-based index, and make that element a string or an object with a "prompt" key
  2. Quote bare numeric prompts: 42 -> "42"
  3. Remove stray null/boolean entries left by merges or templating

Example fix

// before
[
  "a cat",
  7
]

// after
[
  "a cat",
  "7 dogs"
]
Defensive patterns

Strategy: type-guard

Validate before calling

def validate_prompt_items(items: list) -> list[int]:
    return [i for i, item in enumerate(items, start=1) if not isinstance(item, (str, dict))]

Type guard

from typing import Any, TypeGuard

def is_prompt_item(item: Any) -> TypeGuard[str | dict[str, Any]]:
    return isinstance(item, (str, dict))

Try / catch

try:
    load_prompts(prompt_file)
except ValueError as e:
    if "must be a string or object" in str(e):
        idx = int(str(e).split()[2])  # 'Prompt item {index} must be...'
        fix_item_at(prompt_file, idx)

Prevention

When it happens

Trigger: A prompts.json array like ["a cat", 42] or ["a cat", null] — element 2 fails isinstance checks for both str and dict and raises with index 2.

Common situations: Hand-edited prompt lists with a typo (missing quotes around a prompt); trailing null from a bad merge; numbers pasted where prompt text was intended.

Related errors


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