vllm-project/vllm · error · ValueError

Recipe `env` must be an object, got {type(env).__name__}

Error message

Recipe `env` must be an object, got {type(env).__name__}

What it means

write_env() generates an env.sh from the recipe's 'env' field (defaulting to {} when absent/null). If 'env' exists but is not a JSON object — e.g. a list of "K=V" strings or a plain string — the tool cannot iterate it as a mapping and raises this error before writing env.sh.

Source

Thrown at tools/recipes/recipe_json_to_vllm_config.py:604

        f"# Source: {source}",
    ]
    for key in ("hardware", "strategy", "variant", "deploy_type"):
        if recipe.get(key) is not None:
            metadata.append(f"# {key}: {recipe[key]}")

    body = yaml.safe_dump(
        config,
        sort_keys=False,
        default_flow_style=False,
        allow_unicode=True,
    )
    Path(path).write_text("\n".join(metadata) + "\n" + body, encoding="utf-8")


def write_env(path: str, source: str, recipe: dict[str, Any]) -> None:
    env = recipe.get("env") or {}
    if not isinstance(env, dict):
        raise ValueError(f"Recipe `env` must be an object, got {type(env).__name__}")

    lines = [
        "#!/usr/bin/env bash",
        "# Generated from vLLM Recipes JSON.",
        f"# Source: {source}",
        "",
    ]

    if env:
        for key, value in env.items():
            lines.append(f"export {key}={shlex.quote(str(value))}")
    else:
        lines.append("# No recipe-specific environment variables.")

    lines.append("")
    Path(path).write_text("\n".join(lines), encoding="utf-8")
    Path(path).chmod(Path(path).stat().st_mode | 0o111)

View on GitHub (pinned to c794754062)

Solutions

  1. jq '.env' recipe.json to see the actual shape
  2. Convert the env to an object: an array of K=V strings becomes {"K":"V",...}; a single string becomes a one-key object
  3. If the API changed its env serialization format, update the vllm checkout

Example fix

# before
"env": ["VLLM_USE_V1=1", "HF_TOKEN=abc"]
# after
"env": {"VLLM_USE_V1": "1", "HF_TOKEN": "abc"}
Defensive patterns

Strategy: type-guard

Validate before calling

env = recipe.get("env") or {}
if not isinstance(env, dict):
    raise SystemExit(f"env must be object, got {type(env).__name__}")

Type guard

def is_env_object(recipe: dict) -> bool:
    env = recipe.get("env")
    return env is None or isinstance(env, dict)

Prevention

When it happens

Trigger: Recipe JSON where env is rendered as ["VLLM_USE_V1=1"] (array of assignments) or "VLLM_USE_V1=1" (string) instead of {"VLLM_USE_V1": "1"}; schema drift in how the Recipes API serializes environment variables.

Common situations: Third-party recipe files adopting a different env convention; API version change; hand-written env blocks copied from systemd/Docker files (KEY=VALUE lines).

Related errors


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