{"record":{"id":"90c2ff1b79bda4df","repo":"vllm-project/vllm","slug":"hardware-recipe-json-does-not-contain-a-usable-st","errorCode":null,"errorMessage":"Hardware recipe JSON does not contain a usable `strategy` field.","messagePattern":"Hardware recipe JSON does not contain a usable `strategy` field\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/recipes/recipe_json_to_vllm_config.py","lineNumber":269,"sourceCode":"        )\n        if selected is None:\n            raise ValueError(\n                f\"Hardware {requested!r} is not available for this model. \"\n                f\"Available: {', '.join(hardware_ids)}\"\n            )\n        return selected, by_hardware[selected]\n\n    print(\"\\nAvailable hardware:\")\n    selected = choose_from_menu(hardware_ids, lambda value: value, \"Select hardware: \")\n    return selected, by_hardware[selected]\n\n\ndef strategy_sources(\n    api_base: str, hardware_json_url: str, recipe: dict[str, Any]\n) -> tuple[str, dict[str, str]]:\n    recommended = recipe.get(\"strategy\")\n    if not isinstance(recommended, str) or not recommended:\n        raise ValueError(\n            \"Hardware recipe JSON does not contain a usable `strategy` field.\"\n        )\n\n    sources = {recommended: hardware_json_url}\n    raw_alternatives = recipe.get(\"alternatives\") or {}\n    if not isinstance(raw_alternatives, dict):\n        raise ValueError(\n            \"Hardware recipe JSON `alternatives` must be an object when present.\"\n        )\n\n    for strategy, path in raw_alternatives.items():\n        if isinstance(strategy, str) and strategy and isinstance(path, str) and path:\n            sources[strategy] = api_url(api_base, path)\n\n    return recommended, sources\n\n\ndef select_strategy(","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/tools/recipes/recipe_json_to_vllm_config.py#L251-L287","documentation":"strategy_sources() reads the hardware recipe JSON and requires a non-empty string in its top-level 'strategy' field (the recommended serving strategy). If the field is absent, null, empty, or a non-string, this ValueError aborts before alternatives are considered.","triggerScenarios":"Passing a hand-written or edited recipe JSON whose 'strategy' key was removed/renamed/misnested; consuming an upstream recipe file from a different (older/newer) schema version.","commonSituations":"Authoring custom recipe JSONs for internal models; a Recipes API format change leaving 'strategy' out of some entries.","solutions":["Open the recipe JSON and ensure the hardware-level object contains \"strategy\": \"<strategy-id>\" as a non-empty string.","Regenerate or re-download the recipe from the Recipes API to get a schema-conformant file.","Validate the JSON structure against a known-good recipe before passing it."],"exampleFix":"# before (recipe.json)\n{ \"hardware\": { \"h100\": { \"alternatives\": { \"...\": \"...\" } } } }\n# -> ValueError: Hardware recipe JSON does not contain a usable `strategy` field.\n\n# after\n{ \"hardware\": { \"h100\": { \"strategy\": \"tp4-pp2\", \"alternatives\": { \"...\": \"...\" } } } }","handlingStrategy":"type-guard","validationCode":"recommended = recipe.get(\"strategy\")\nif not isinstance(recommended, str) or not recommended:\n    raise SystemExit(\"recipe JSON lacks a usable 'strategy' string; fix or regenerate the file\")","typeGuard":"def has_usable_strategy(recipe: dict) -> bool:\n    return isinstance(recipe.get(\"strategy\"), str) and bool(recipe[\"strategy\"].strip())","tryCatchPattern":null,"preventionTips":["Schema-validate recipe JSON files before passing them to the tool.","Regenerate custom recipes from the Recipes API when the format changes."],"tags":["cli","recipes","json","validation","tooling"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}