vllm-project/vllm · error · ValueError

{model_json_url} did not return a JSON object.

Error message

{model_json_url} did not return a JSON object.

What it means

The converter resolved the per-model JSON URL (model['json'] joined with the API base) and fetched it successfully, but the parsed JSON was not an object (e.g. it was a list, string, number, or null). The recipe schema requires a top-level JSON object, so any other shape is rejected immediately after load_json() in discover_recipe_source().

Source

Thrown at tools/recipes/recipe_json_to_vllm_config.py:350

) -> str:
    print("No recipe JSON supplied; starting Recipes API discovery.")

    models_url = api_url(api_base, "/models.json")
    models_data = load_json(models_url)
    if not isinstance(models_data, list):
        raise ValueError(f"{models_url} did not return a model list.")

    models = [model for model in models_data if isinstance(model, dict)]
    model = select_model(models, requested_model)

    model_json_path = model.get("json")
    if not isinstance(model_json_path, str) or not model_json_path:
        raise ValueError(f"Selected model {model.get('hf_id')!r} has no JSON API path.")

    model_json_url = api_url(api_base, model_json_path)
    model_data = load_json(model_json_url)
    if not isinstance(model_data, dict):
        raise ValueError(f"{model_json_url} did not return a JSON object.")

    recommended = model_data.get("recommended_command")
    if not isinstance(recommended, dict):
        raise ValueError(
            f"Model {model.get('hf_id')!r} has no rendered "
            "recommended_command in the Recipes API."
        )

    raw_by_hardware = recommended.get("by_hardware")
    if not isinstance(raw_by_hardware, dict) or not raw_by_hardware:
        raise ValueError(
            f"Model {model.get('hf_id')!r} has no per-hardware renderings "
            "in recommended_command.by_hardware."
        )

    by_hardware = {
        str(hw): path
        for hw, path in raw_by_hardware.items()

View on GitHub (pinned to c794754062)

Solutions

  1. curl the exact model_json_url shown in the error and inspect the top-level JSON type (object vs list)
  2. If the URL is wrong, fix the 'json' path in the models.json source or update to a vllm checkout matching the live API layout
  3. If the content is wrong server-side, fetch a valid per-hardware recipe JSON and pass it positionally to skip this code path

Example fix

# before
python tools/recipes/recipe_json_to_vllm_config.py --model org/model  # URL returns [..]
# after: verify and use the direct hardware recipe
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

import json, urllib.request
obj = json.load(urllib.request.urlopen(model_json_url))
if not isinstance(obj, dict):
    raise SystemExit(f"{model_json_url} is {type(obj).__name__}, expected object")

Type guard

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

Prevention

When it happens

Trigger: The model['json'] path resolves to an endpoint that returns a JSON array or scalar instead of an object — e.g. a path that actually points at a list endpoint, a stale/cached response, or a proxy returning a JSON-wrapped error like "not found".

Common situations: Recipes API path layout changes so the 'json' field points at the wrong resource type; a CDN/mirror serving a directory listing (JSON array) instead of the model document; hand-edited models.json entries with incorrect paths.

Related errors


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