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
- Change 'alternatives' to an object: {"<strategy-id>": "<path-or-url>", ...} or remove it entirely (it is optional).
- 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
- Keep 'alternatives' an object of string->string pairs or omit it.
- Lint recipe JSON with a schema checker in CI for custom recipe files.
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
- Hardware recipe JSON does not contain a usable `strategy` fi
- Hardware {requested!r} is not available for this model. Avai
- Strategy {requested!r} is not available for this model/hardw
- No selectable items found.
- No recipe model matched {requested!r}.
AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14).
Data as JSON: /api/errors/5117c2cbd7c31eba.
Report an issue: GitHub.