{"record":{"id":"abd878b89d508907","repo":"vllm-project/vllm","slug":"interactive-input-is-unavailable-pass-model-and","errorCode":null,"errorMessage":"Interactive input is unavailable. Pass --model and --hardware, or provide a recipe JSON URL/file.","messagePattern":"Interactive input is unavailable\\. Pass --model and --hardware, or provide a recipe JSON URL/file\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/recipes/recipe_json_to_vllm_config.py","lineNumber":144,"sourceCode":"\ndef load_json(source: str) -> dict[str, Any] | list[Any]:\n    if source.startswith((\"http://\", \"https://\")):\n        req = urllib.request.Request(\n            source,\n            headers={\"User-Agent\": \"vllm-recipe-config-converter/1.0\"},\n        )\n        with urllib.request.urlopen(req, timeout=30) as response:\n            return json.load(response)\n\n    with open(source, encoding=\"utf-8\") as f:\n        return json.load(f)\n\n\ndef prompt(text: str) -> str:\n    try:\n        return input(text).strip()\n    except EOFError as exc:\n        raise ValueError(\n            \"Interactive input is unavailable. Pass --model and --hardware, \"\n            \"or provide a recipe JSON URL/file.\"\n        ) from exc\n\n\ndef model_label(model: dict[str, Any]) -> str:\n    label = str(model.get(\"hf_id\", \"\"))\n    title = model.get(\"title\")\n    provider = model.get(\"provider\")\n    if title and title != label:\n        label += f\" — {title}\"\n    if provider:\n        label += f\" [{provider}]\"\n    return label\n\n\ndef search_models(\n    models: list[dict[str, Any]], query: str, limit: int = 20","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/tools/recipes/recipe_json_to_vllm_config.py#L126-L162","documentation":"When no recipe JSON source is given, the tool falls back to an interactive model/hardware picker that reads from stdin. prompt() catches EOFError (closed stdin, no TTY, CI) and converts it into this ValueError telling you to supply the non-interactive arguments instead.","triggerScenarios":"Invoking recipe_json_to_vllm_config.py in CI/piped context without --model/--hardware and without a recipe JSON URL/file, so the first input() hits EOF.","commonSituations":"Scripting the tool in automation with stdin closed; running it under a non-interactive shell where the discovery flow starts but cannot prompt.","solutions":["Pass explicit flags: `--model <query> --hardware <id>` (and optionally `--strategy`).","Or supply the recipe JSON directly via URL/path so discovery never prompts.","For local exploration, run inside a real terminal so prompts work."],"exampleFix":"# before (CI job)\npython tools/recipes/recipe_json_to_vllm_config.py < /dev/null\n# -> ValueError: Interactive input is unavailable...\n\n# after\npython tools/recipes/recipe_json_to_vllm_config.py --model \"llama 3.1\" --hardware h100","handlingStrategy":"validation","validationCode":"import sys\nnon_interactive = not sys.stdin.isatty()\nif non_interactive and not (args.model and args.hardware) and not args.recipe:\n    raise SystemExit(\"Non-interactive run needs --model/--hardware or a recipe JSON URL/file\")","typeGuard":null,"tryCatchPattern":"try:\n    value = input(prompt)\nexcept EOFError:\n    raise SystemExit(\"No TTY: pass --model and --hardware explicitly\") from None","preventionTips":["Always pass --model/--hardware (or the recipe JSON) when scripting the tool.","Detect CI/non-TTY contexts up front and fail fast with an actionable message."],"tags":["cli","interactive-prompt","ci","tooling"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}