langchain-ai/deepagents · error · RuntimeError

RubricMiddleware grader did not return a structured_response

Error message

RubricMiddleware grader did not return a structured_response. The grader sub-agent must use response_format=GraderResponse.

What it means

RubricMiddleware invokes a grader sub-agent created with response_format=GraderResponse and reads its result from structured_response. If the grader's result dict has no structured_response, the grader was constructed without a structured output format (or returned malformed/empty output), so the middleware raises RuntimeError instead of producing a bogus grade.

Source

Thrown at libs/deepagents/deepagents/middleware/rubric.py:1076

        self._record_grader_trace_metadata(metadata)
        result = await grader.ainvoke(
            self._grader_input(state, iteration, correction),
            config=self._grader_invocation_config(metadata),
            context=context,
        )
        self._record_grader_trace_metadata(
            self._grader_trace_metadata(
                effective_strategy=_strategy_from_result(result),
            )
        )
        return self._extract_graded(result)

    @staticmethod
    def _extract_graded(result: dict[str, Any]) -> GraderResponse:
        graded = result.get("structured_response")
        if graded is None:
            msg = "RubricMiddleware grader did not return a structured_response. The grader sub-agent must use response_format=GraderResponse."
            raise RuntimeError(msg)
        if not isinstance(graded, GraderResponse):
            # `create_agent` returns whatever the grader's response_format
            # resolves to; we expect a `GraderResponse` instance but accept
            # a `dict` for forward-compat.
            if isinstance(graded, dict):
                graded = GraderResponse.model_validate(graded)
            else:
                msg = f"RubricMiddleware grader returned unexpected structured_response of type {type(graded).__name__}."
                raise TypeError(msg)
        return graded

    def _build_grader_payload(
        self,
        state: RubricState,
        iteration: int,
        correction: str | None = None,
    ) -> str:
        """Assemble the grader's first user message.

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Create the grader with create_agent(..., response_format=GraderResponse).
  2. If using a custom grader, ensure its result dict includes structured_response as a GraderResponse (or dict matching it).
  3. Verify the grader model supports structured output / tool-calling for the response format.
  4. Log the raw grader result to check for empty or errored runs.

Example fix

// before
grader = create_agent(model, tools=[...])
// after
grader = create_agent(model, tools=[...], response_format=GraderResponse)
Defensive patterns

Strategy: try-catch

Validate before calling

grader = create_agent(model, tools=tools, response_format=GraderResponse)
assert grader is not None

Type guard

def grader_supports_structured(agent: object) -> bool:
    return getattr(agent, "response_format", None) is GraderResponse or hasattr(agent, "structured_response")

Try / catch

try:
    graded = middleware._extract_graded(result)
except RuntimeError as e:
    if "structured_response" in str(e):
        # rebuild grader with response_format=GraderResponse and retry once
        ...
    else:
        raise

Prevention

When it happens

Trigger: Grader sub-agent built without response_format=GraderResponse; grader model failed to produce structured output; a custom grader callable returning a plain dict without a structured_response key.

Common situations: Swapping the grader model for one that ignores response_format; wiring a custom grader agent that returns text content; upgrading the library and pointing it at a hand-rolled grader that doesn't emit structured responses.

Related errors


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