{"record":{"id":"a8a3f6f8628eb288","repo":"vllm-project/vllm","slug":"selected-model-model-get-hf-id-r-has-no-json","errorCode":null,"errorMessage":"Selected model {model.get('hf_id')!r} has no JSON API path.","messagePattern":"Selected model (.+?) has no JSON API path\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/recipes/recipe_json_to_vllm_config.py","lineNumber":345,"sourceCode":"def discover_recipe_source(\n    api_base: str,\n    requested_model: str | None,\n    requested_hardware: str | None,\n    requested_strategy: str | None,\n) -> str:\n    print(\"No recipe JSON supplied; starting Recipes API discovery.\")\n\n    models_url = api_url(api_base, \"/models.json\")\n    models_data = load_json(models_url)\n    if not isinstance(models_data, list):\n        raise ValueError(f\"{models_url} did not return a model list.\")\n\n    models = [model for model in models_data if isinstance(model, dict)]\n    model = select_model(models, requested_model)\n\n    model_json_path = model.get(\"json\")\n    if not isinstance(model_json_path, str) or not model_json_path:\n        raise ValueError(f\"Selected model {model.get('hf_id')!r} has no JSON API path.\")\n\n    model_json_url = api_url(api_base, model_json_path)\n    model_data = load_json(model_json_url)\n    if not isinstance(model_data, dict):\n        raise ValueError(f\"{model_json_url} did not return a JSON object.\")\n\n    recommended = model_data.get(\"recommended_command\")\n    if not isinstance(recommended, dict):\n        raise ValueError(\n            f\"Model {model.get('hf_id')!r} has no rendered \"\n            \"recommended_command in the Recipes API.\"\n        )\n\n    raw_by_hardware = recommended.get(\"by_hardware\")\n    if not isinstance(raw_by_hardware, dict) or not raw_by_hardware:\n        raise ValueError(\n            f\"Model {model.get('hf_id')!r} has no per-hardware renderings \"\n            \"in recommended_command.by_hardware.\"","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/tools/recipes/recipe_json_to_vllm_config.py#L327-L363","documentation":"Raised by the Recipes API discovery flow in tools/recipes/recipe_json_to_vllm_config.py. After fetching {api_base}/models.json and letting the user pick a model (interactively or via --model), the selected model entry must contain a non-empty string under the 'json' key pointing at its per-model recipe JSON. If that field is missing, null, or not a string, the tool aborts because it has no URL to fetch the recipe from.","triggerScenarios":"Running the converter with no positional source (discovery mode), or with --model HF_ID, where the selected entry in models.json lacks a valid 'json' field. Typically caused by Recipes API schema drift, a partially-published model entry, or a hand-crafted models.json used with --api-base.","commonSituations":"Pointing --api-base at a mirror/staging Recipes server with incomplete entries; running an outdated checkout against a newer API schema (field renamed, e.g. 'json' -> 'recipe_json'); selecting a model that is listed but has no rendered recipes yet.","solutions":["Inspect the model list yourself (e.g. curl $API_BASE/models.json | jq '.[] | select(.hf_id==\"MODEL\")') and confirm the 'json' field exists and is a non-empty string","If the field is missing on the server, bypass discovery: fetch a known per-hardware recipe JSON URL and pass it as the positional source argument","If the API schema changed (field renamed), update the checkout of vllm so the converter matches the live API","File/fix the server-side entry if you control the Recipes API deployment"],"exampleFix":"# before (discovery hits a model entry without 'json')\npython tools/recipes/recipe_json_to_vllm_config.py --model Qwen/Qwen3-8B\n# after (pass the per-hardware recipe JSON directly)\ncurl -o recipe.json https://recipes.vllm.ai/recipes/Qwen/Qwen3-8B/h100.json\npython tools/recipes/recipe_json_to_vllm_config.py recipe.json","handlingStrategy":"validation","validationCode":"import json, urllib.request\ndata = json.load(urllib.request.urlopen(f\"{API_BASE}/models.json\"))\nmodels = [m for m in data if isinstance(m, dict)]\nselected = next(m for m in models if m.get(\"hf_id\") == MODEL_ID)\nassert isinstance(selected.get(\"json\"), str) and selected[\"json\"], \"model entry lacks usable 'json' path\"","typeGuard":"def has_json_path(model: dict) -> bool:\n    return isinstance(model.get(\"json\"), str) and bool(model[\"json\"].strip())","tryCatchPattern":null,"preventionTips":["Pin the vllm/Recipes API version pair you develop against","Validate models.json entries before driving the interactive discovery","In CI, pass a known-good per-hardware recipe URL instead of relying on live discovery"],"tags":["vllm-recipes","api-discovery","schema-validation"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}