calesthio/OpenMontage · error · ValueError

Image Omni prompt placeholders must start at <<<image_1>>>

Error message

Image Omni prompt placeholders must start at <<<image_1>>>

What it means

Raised when the prompt contains <<<image_N>>> placeholders and the smallest N is less than 1 — i.e. a <<<image_0>>> (or lower) placeholder is present. Kling Image Omni placeholders are 1-based, so image_0 is never valid.

Source

Thrown at tools/_kling/omni.py:36

        {
            "index": index,
            "placeholder": f"<<<image_{index}>>>",
            "source": item.get("source") or item.get("image") or item.get("image_url"),
            "source_type": item.get("source_type", "unknown"),
        }
        for index, item in enumerate(image_list, start=1)
    ]
    if not references:
        return prompt, []

    existing_numbers = [int(value) for value in PLACEHOLDER_RE.findall(prompt)]
    if existing_numbers:
        if max(existing_numbers) > len(references):
            raise ValueError(
                f"prompt references <<<image_{max(existing_numbers)}>>> but only {len(references)} image(s) were provided"
            )
        if min(existing_numbers) < 1:
            raise ValueError("Image Omni prompt placeholders must start at <<<image_1>>>")
        return prompt, references

    placeholders = " ".join(item["placeholder"] for item in references)
    return f"{prompt}\nReferences: {placeholders}", references

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Renumber placeholders to start at <<<image_1>>> (1-based)
  2. If generating prompts programmatically, use enumerate(images, start=1)
  3. Remove the invalid placeholder entirely if it was accidental

Example fix

// before
prompt = f'blend <<<image_0>>> and <<<image_1>>>'  # 0-based, invalid

// after
prompt = 'blend <<<image_1>>> and <<<image_2>>>'  # 1-based
# or programmatically:
parts = [f'<<<image_{i}>>>' for i in range(1, len(images) + 1)]
Defensive patterns

Strategy: validation

Validate before calling

import re

def placeholders_are_one_based(prompt: str) -> bool:
    nums = [int(n) for n in re.findall(r'<<<image_(\-?\d+)>>>', prompt)]
    return not nums or min(nums) >= 1

Try / catch

try:
    prompt, refs = build_image_references(prompt, images)
except ValueError as e:
    if 'must start at <<<image_1>>>' in str(e):
        prompt = prompt.replace('<<<image_0>>>', '<<<image_1>>>')  # fix 0-based prompt
        prompt, refs = build_image_references(prompt, images)
    else:
        raise

Prevention

When it happens

Trigger: A prompt generated with 0-based indexing (common from code or LLMs that enumerate from 0), e.g. 'replace <<<image_0>>> with the product' with any number of references.

Common situations: Prompts written by looping code using enumerate() without start=1; LLM-authored prompts mixing 0-based and 1-based placeholders; template copy-paste from 0-based examples.

Related errors


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