{"record":{"id":"39692cf9121965ee","repo":"vllm-project/vllm","slug":"expected-model-after-vllm-serve-got-model-r","errorCode":null,"errorMessage":"Expected model after 'vllm serve', got {model!r}","messagePattern":"Expected model after 'vllm serve', got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/recipes/recipe_json_to_vllm_config.py","lineNumber":470,"sourceCode":"    Nested JSON field names after a dot are preserved.\n    \"\"\"\n    parts = raw_key.split(\".\")\n    parts[0] = parts[0].replace(\"_\", \"-\")\n    return parts\n\n\ndef argv_to_config(argv: list[Any]) -> dict[str, Any]:\n    argv = [str(x) for x in argv]\n\n    if len(argv) < 3 or argv[0:2] != [\"vllm\", \"serve\"]:\n        raise ValueError(\n            \"Expected recipe argv to start with: ['vllm', 'serve', MODEL, ...]. \"\n            f\"Got: {argv[:4]!r}\"\n        )\n\n    model = argv[2]\n    if model.startswith(\"-\"):\n        raise ValueError(f\"Expected model after 'vllm serve', got {model!r}\")\n\n    config: dict[str, Any] = {\"model\": model}\n\n    i = 3\n    while i < len(argv):\n        token = argv[i]\n\n        # -O3 / -O=3\n        if token.startswith(\"-O\") and token != \"-O\":\n            value = token[3:] if token.startswith(\"-O=\") else token[2:]\n            merge_value(config, [\"optimization-level\"], coerce(value))\n            i += 1\n            continue\n\n        # -O 3\n        if token == \"-O\":\n            if i + 1 >= len(argv):\n                raise ValueError(\"-O is missing its value\")","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/tools/recipes/recipe_json_to_vllm_config.py#L452-L488","documentation":"After validating the ['vllm','serve'] prefix, argv_to_config() checks that argv[2] (the model) does not start with '-'. A leading dash means the token is a flag, so the positional model is missing — e.g. ['vllm','serve','--port','8000'] with the model forgotten or placed later.","triggerScenarios":"Recipe rendering that emits flags before the model; model field empty and dropped from argv leaving a flag at index 2; hand-built argv where the model was omitted by accident.","commonSituations":"Recipes renderer bug for models with empty ids; editing recipe JSON and deleting the model token; schema where the model is supposed to be supplied separately but argv still contains only options.","solutions":["jq '.argv' recipe.json and look at argv[2]","Insert the model id at position 2 (right after 'serve') in the recipe JSON","If the recipe is API-rendered with the model missing, report the model's recipe as broken and pick another model/hardware recipe"],"exampleFix":"# before\n\"argv\": [\"vllm\", \"serve\", \"--max-model-len\", \"8192\"]\n# after\n\"argv\": [\"vllm\", \"serve\", \"meta-llama/Llama-3-8B\", \"--max-model-len\", \"8192\"]","handlingStrategy":"validation","validationCode":"argv = [str(x) for x in recipe[\"argv\"]]\nif len(argv) > 2 and argv[2].startswith(\"-\"):\n    raise SystemExit(\"argv[2] must be the model id, got a flag\")","typeGuard":"def argv_has_model(argv: list) -> bool:\n    argv = [str(x) for x in argv]\n    return len(argv) >= 3 and not argv[2].startswith(\"-\")","tryCatchPattern":null,"preventionTips":["Validate the model slot right after validating the vllm serve prefix","Render model id before flags in any argv you generate"],"tags":["vllm-recipes","argv-parsing","cli"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}