calesthio/OpenMontage · error · ValueError

model must be one of: sora-2, sora-2-pro

Error message

model must be one of: sora-2, sora-2-pro

What it means

ValueError raised by SoraVideo._normalize_model when the 'model' input, after strip+lowercase, is not in _ALLOWED_MODELS. Only the two OpenAI video models 'sora-2' and 'sora-2-pro' are accepted; anything else — including plausible names like 'sora', 'sora-2-turbo', or other providers' model ids — is rejected before any API call.

Source

Thrown at tools/video/sora_video.py:239

        if cls._version_tuple(getattr(openai, "__version__", "")) < _MIN_OPENAI_VERSION:
            return False
        return hasattr(OpenAI(), "videos")

    @staticmethod
    def _version_tuple(version: str) -> tuple[int, int, int]:
        parts = []
        for part in version.split(".")[:3]:
            digits = "".join(ch for ch in part if ch.isdigit())
            parts.append(int(digits or "0"))
        while len(parts) < 3:
            parts.append(0)
        return tuple(parts)

    @staticmethod
    def _normalize_model(inputs: dict[str, Any]) -> str:
        model = str(inputs.get("model", _DEFAULT_MODEL)).strip().lower()
        if model not in _ALLOWED_MODELS:
            raise ValueError("model must be one of: sora-2, sora-2-pro")
        return model

    @staticmethod
    def _normalize_size(inputs: dict[str, Any], model: str) -> str:
        default_size = "1280x720" if inputs.get("aspect_ratio") == "16:9" else _DEFAULT_SIZE
        size = str(inputs.get("size", default_size)).strip().lower()
        allowed = {"1280x720", "720x1280"} if model == "sora-2" else set(_ALLOWED_SIZES)
        if size not in allowed:
            raise ValueError(f"size must be one of: {', '.join(sorted(allowed))} for model {model}")
        return size

    @staticmethod
    def _normalize_seconds(inputs: dict[str, Any]) -> str:
        seconds = str(inputs.get("seconds") or inputs.get("duration") or _DEFAULT_SECONDS).strip().lower()
        seconds = seconds[:-1] if seconds.endswith("s") else seconds
        if seconds not in _ALLOWED_SECONDS:
            raise ValueError("seconds must be one of: 4, 8, 12")
        return seconds

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Use exactly 'sora-2' or 'sora-2-pro'.
  2. If your deployment uses a custom name (Azure-style), remove the model override and let the default apply, or map your deployment name to one of the allowed values at your call site.
  3. Omit model to fall back to _DEFAULT_MODEL.

Example fix

# before
inputs = {"model": "sora-2-turbo"}

# after
inputs = {"model": "sora-2-pro"}
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = {"sora-2", "sora-2-pro"}
model = str(inputs.get("model", "sora-2")).strip().lower()
if model not in ALLOWED:
    inputs["model"] = "sora-2"

Type guard

def is_valid_sora_model(v) -> bool:
    return str(v).strip().lower() in {"sora-2", "sora-2-pro"}

Prevention

When it happens

Trigger: Passing model='sora', model='soravideo', model='dangao-2' (the Chinese-market alias), or leaving trailing junk like 'sora-2 '. (Note trailing whitespace alone is stripped, so ' Sora-2 ' is fine.)

Common situations: Model lists copy-pasted from news articles or other gateways (Azure OpenAI deployments use custom deployment names like 'my-sora-deployment'); version drift after new Sora releases when users guess at names.

Related errors


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