langchain-ai/deepagents · error · ValueError

response_schema cannot be used with compiled subagent "{spec

Error message

response_schema cannot be used with compiled subagent "{spec["name"]}"; dynamic schemas require a raw SubAgent spec.

What it means

`_compile_spec` accepts either a raw declarative `SubAgent` spec or an already-compiled runnable (`CompiledSubAgent` with a `runnable` key). Structured-output `response_schema` can only be injected while compiling a raw spec; passing it alongside a pre-compiled subagent raises `ValueError` because the runnable is already built.

Source

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

            uses default template. Supports `{available_agents}` placeholder.
        private_state_keys: State keys marked with `PrivateStateAttr` that
            should be stripped from parent state before invoking subagents.
        state_schema: Base graph state schema forwarded to raw subagent specs.

    Returns:
        A StructuredTool that can invoke subagents by type.
    """

    def _compile_spec(
        spec: SubAgent | CompiledSubAgent,
        *,
        response_format: ResponseFormat[Any] | type | dict[str, Any] | None = None,
    ) -> CompiledSubAgent:
        """Compile one raw spec or configure one provided runnable."""
        if "runnable" in spec:
            if response_format is not None:
                msg = f'response_schema cannot be used with compiled subagent "{spec["name"]}"; dynamic schemas require a raw SubAgent spec.'
                raise ValueError(msg)

            # Use with_config (not attribute mutation) so the original runnable is
            # untouched and a shared instance can be registered under multiple names.
            compiled = cast("CompiledSubAgent", spec)
            runnable = compiled["runnable"].with_config(
                {
                    "metadata": {"lc_agent_name": spec["name"]},
                    "run_name": spec["name"],
                }
            )
            return {
                "name": spec["name"],
                "description": spec["description"],
                "runnable": runnable,
            }
        return {
            "name": spec["name"],
            "description": spec["description"],

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Remove `response_schema` for subagents registered as compiled runnables
  2. Convert the entry to a raw declarative spec (model/tools/...) so `response_schema` can be applied at compile time
  3. Bake structured output into the runnable itself (e.g. `with_structured_output`) before registering it

Example fix

// before
middleware.task(response_schema=MySchema, subagents=[{"name": "a", "runnable": compiled}])
// after
subagents=[{"name": "a", "model": "openai:gpt-4.1", "tools": [], "response_schema": MySchema}]
Defensive patterns

Strategy: validation

Validate before calling

if response_schema is not None and "runnable" in spec:
    raise TypeError("response_schema requires a raw SubAgent spec, not a compiled runnable")

Type guard

def is_raw_spec(spec: dict) -> bool:
    return "runnable" not in spec

Try / catch

try:
    compile_spec(spec, response_format=schema)
except ValueError as e:
    logger.error("%s — convert to a raw spec or drop response_schema", e)
    raise

Prevention

When it happens

Trigger: Calling `task`/`SubAgentMiddleware` machinery with both a subagent entry whose dict contains `"runnable"` and a non-None `response_schema` argument.

Common situations: Mixing declarative and pre-compiled subagent registrations in one config; adding structured output support to an existing compiled-graph registration without converting it back to a raw spec.

Related errors


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