langchain-ai/deepagents · error · ValueError

SubAgent '{spec['name']}' must specify 'tools'

Error message

SubAgent '{spec['name']}' must specify 'tools'

What it means

Like `model`, a `SubAgent` spec must declare `tools`. If the `tools` key is missing, `create_sub_agent` raises `ValueError`. The library requires the key to be present (even an empty list) so intent is explicit rather than inferred.

Source

Thrown at libs/deepagents/deepagents/middleware/subagents.py:365

    Args:
        spec: Subagent spec to compile. Must specify `model` and `tools`.
        state_schema: Base graph state schema forwarded to `create_agent` for
            the subagent.
        response_format: Optional response format override for this compiled
            subagent instance.

    Returns:
        Runnable agent ready for task-tool invocation.

    Raises:
        ValueError: If `spec` is missing `model` or `tools`.
    """
    if "model" not in spec:
        msg = f"SubAgent '{spec['name']}' must specify 'model'"
        raise ValueError(msg)
    if "tools" not in spec:
        msg = f"SubAgent '{spec['name']}' must specify 'tools'"
        raise ValueError(msg)

    from deepagents._models import resolve_model  # noqa: PLC0415

    model = resolve_model(spec["model"])
    middleware: list[AgentMiddleware] = list(spec.get("middleware", []))

    interrupt_on = spec.get("interrupt_on")
    if interrupt_on:
        middleware.append(HumanInTheLoopMiddleware(interrupt_on=interrupt_on))

    selected_response_format = response_format if response_format is not None else spec.get("response_format")
    create_agent_kwargs: dict[str, Any] = {
        "system_prompt": spec["system_prompt"],
        "tools": spec["tools"],
        "middleware": middleware,
        "name": spec["name"],
        "response_format": selected_response_format,
    }

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Add a `tools` key; use `[]` for a tools-free subagent
  2. List the intended tool callables under `tools`
  3. Check for key typos and that config loading doesn't drop empty lists

Example fix

// before
{"name": "planner", "model": "openai:gpt-4.1"}
// after
{"name": "planner", "model": "openai:gpt-4.1", "tools": []}
Defensive patterns

Strategy: validation

Validate before calling

if "tools" not in spec:
    raise ValueError(f"spec {spec.get('name')!r} missing 'tools'; use [] for none")

Type guard

def has_tools_key(spec: dict) -> bool:
    return "tools" in spec

Try / catch

try:
    agent = create_sub_agent(spec=spec)
except ValueError as e:
    logger.error("Subagent spec needs tools: %s", e)
    raise

Prevention

When it happens

Trigger: Calling `create_sub_agent(spec=...)` with a dict containing `name` and `model` but no `tools` key.

Common situations: Authoring read-only/reasoning subagents and assuming tools are optional; YAML/JSON configs where the tools list was omitted; typos like `tool` instead of `tools`.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/ad43ddcb17dac1af. Report an issue: GitHub.