vllm-project/vllm · error · ValueError

Hardware recipe JSON `alternatives` must be an object when p

Error message

Hardware recipe JSON `alternatives` must be an object when present.

What it means

In the same recipe JSON, the optional 'alternatives' field must be a JSON object mapping strategy names to paths. strategy_sources() raises this ValueError when 'alternatives' is present but not a dict (e.g. a list or string).

Source

Thrown at tools/recipes/recipe_json_to_vllm_config.py:276

    print("\nAvailable hardware:")
    selected = choose_from_menu(hardware_ids, lambda value: value, "Select hardware: ")
    return selected, by_hardware[selected]


def strategy_sources(
    api_base: str, hardware_json_url: str, recipe: dict[str, Any]
) -> tuple[str, dict[str, str]]:
    recommended = recipe.get("strategy")
    if not isinstance(recommended, str) or not recommended:
        raise ValueError(
            "Hardware recipe JSON does not contain a usable `strategy` field."
        )

    sources = {recommended: hardware_json_url}
    raw_alternatives = recipe.get("alternatives") or {}
    if not isinstance(raw_alternatives, dict):
        raise ValueError(
            "Hardware recipe JSON `alternatives` must be an object when present."
        )

    for strategy, path in raw_alternatives.items():
        if isinstance(strategy, str) and strategy and isinstance(path, str) and path:
            sources[strategy] = api_url(api_base, path)

    return recommended, sources


def select_strategy(
    api_base: str,
    hardware_json_url: str,
    recipe: dict[str, Any],
    requested: str | None,
    interactive: bool,
) -> tuple[str, str]:
    recommended, sources = strategy_sources(api_base, hardware_json_url, recipe)

View on GitHub (pinned to c794754062)

Solutions

  1. Change 'alternatives' to an object: {"<strategy-id>": "<path-or-url>", ...} or remove it entirely (it is optional).
  2. Validate the file with a JSON schema check before passing it to the tool.

Example fix

# before
"alternatives": ["tp8", "tp4-pp2"]
# -> ValueError: Hardware recipe JSON `alternatives` must be an object when present.

# after
"alternatives": {"tp8": "tp8.json", "tp4-pp2": "tp4-pp2.json"}
Defensive patterns

Strategy: type-guard

Validate before calling

alts = recipe.get("alternatives")
if alts is not None and not isinstance(alts, dict):
    raise SystemExit("'alternatives' must be an object mapping strategy -> path")

Type guard

def has_valid_alternatives(recipe: dict) -> bool:
    alts = recipe.get("alternatives")
    return alts is None or (
        isinstance(alts, dict)
        and all(isinstance(k, str) and isinstance(v, str) for k, v in alts.items())
    )

Prevention

When it happens

Trigger: Hand-editing a recipe JSON so 'alternatives' becomes an array or scalar; merging recipe files with a tool that changed the value's type.

Common situations: Custom recipe authoring; schema drift between recipe file versions.

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/5117c2cbd7c31eba. Report an issue: GitHub.