vllm-project/vllm · error · ValueError

Recipe JSON must be a JSON object.

Error message

Recipe JSON must be a JSON object.

What it means

In main(), after load_json(source) succeeds, the top-level recipe must be a JSON object (dict). If the source file/URL contains a JSON list, string, number, or null, there is no recipe structure to read deploy_type/argv/env from, so the tool fails immediately.

Source

Thrown at tools/recipes/recipe_json_to_vllm_config.py:641

def main() -> int:
    args = parse_args()

    try:
        source = args.source
        if source is None:
            source = discover_recipe_source(
                args.api_base, args.model, args.hardware, args.strategy
            )
        elif args.model or args.hardware or args.strategy:
            raise ValueError(
                "Do not combine a positional recipe JSON source with "
                "--model/--hardware/--strategy discovery options."
            )

        recipe = load_json(source)
        if not isinstance(recipe, dict):
            raise ValueError("Recipe JSON must be a JSON object.")

        argv = recipe_argv(recipe)
        config = argv_to_config(argv)
        write_config(args.config_out, source, recipe, config)
        write_env(args.env_out, source, recipe)
    except Exception as exc:
        print(f"ERROR: {exc}", file=sys.stderr)
        return 1

    print(f"Wrote {args.config_out}")
    print(f"Wrote {args.env_out}")
    print()
    print("Run:")
    print(f"  source {shlex.quote(args.env_out)}")
    print(f"  vllm serve --config {shlex.quote(args.config_out)}")
    return 0

View on GitHub (pinned to c794754062)

Solutions

  1. Check the source's top-level type: jq -r 'type' recipe.json (must report 'object')
  2. If it is a list of recipes, pick the right element and save just that object as the file
  3. Make sure you passed the per-hardware recipe JSON URL/file, not models.json or a listing endpoint

Example fix

# before
python tools/recipes/recipe_json_to_vllm_config.py https://recipes.vllm.ai/models.json
# after
python tools/recipes/recipe_json_to_vllm_config.py https://recipes.vllm.ai/recipes/org/model/h100.json
Defensive patterns

Strategy: validation

Validate before calling

recipe = json.loads(Path(source).read_text())
if not isinstance(recipe, dict):
    raise SystemExit(f"top-level JSON is {type(recipe).__name__}, must be object")

Type guard

def is_json_object(x: object) -> bool:
    return isinstance(x, dict)

Prevention

When it happens

Trigger: Passing a URL/path whose JSON is an array — e.g. pointing the tool at models.json (a list) instead of a per-hardware recipe object; passing a .json that contains a bare string; a truncated file that parses to null.

Common situations: Confusing the API's model list endpoint with a recipe endpoint; test fixtures with wrong top-level type; API returning a JSON array of recipes for a listing path.

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/b6e74e4ac9de4137. Report an issue: GitHub.