{"record":{"id":"69d314c933dec3aa","repo":"langchain-ai/deepagents","slug":"rubricmiddleware-grader-returned-unexpected-struct","errorCode":null,"errorMessage":"RubricMiddleware grader returned unexpected structured_response of type {type(graded).__name__}.","messagePattern":"RubricMiddleware grader returned unexpected structured_response of type (.+?)\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/middleware/rubric.py","lineNumber":1085,"sourceCode":"            )\n        )\n        return self._extract_graded(result)\n\n    @staticmethod\n    def _extract_graded(result: dict[str, Any]) -> GraderResponse:\n        graded = result.get(\"structured_response\")\n        if graded is None:\n            msg = \"RubricMiddleware grader did not return a structured_response. The grader sub-agent must use response_format=GraderResponse.\"\n            raise RuntimeError(msg)\n        if not isinstance(graded, GraderResponse):\n            # `create_agent` returns whatever the grader's response_format\n            # resolves to; we expect a `GraderResponse` instance but accept\n            # a `dict` for forward-compat.\n            if isinstance(graded, dict):\n                graded = GraderResponse.model_validate(graded)\n            else:\n                msg = f\"RubricMiddleware grader returned unexpected structured_response of type {type(graded).__name__}.\"\n                raise TypeError(msg)\n        return graded\n\n    def _build_grader_payload(\n        self,\n        state: RubricState,\n        iteration: int,\n        correction: str | None = None,\n    ) -> str:\n        \"\"\"Assemble the grader's first user message.\n\n        Wraps the caller-supplied rubric and the transcript in\n        nonce-bracketed delimiters and scrubs any literal closing tags\n        from the content before interpolation.\n\n        Two modes. With no frozen criterion list the grader is asked to\n        enumerate the rubric itself; once a list exists it is replayed as a\n        numbered checklist and the grader is asked for that exact count, which\n        keeps the criterion set from shrinking across iterations of one run.","sourceCodeStart":1067,"sourceCodeEnd":1103,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/middleware/rubric.py#L1067-L1103","documentation":"After reading structured_response, the middleware expects a GraderResponse instance and tolerates a dict (validated via pydantic) for forward-compatibility. Any other type means the grader's response_format resolved to something unexpected, so a TypeError is raised to surface the mismatch.","triggerScenarios":"A custom grader agent whose response_format is a different pydantic model, so structured_response is e.g. MyOtherModel; a hand-rolled grader returning an arbitrary object in structured_response.","commonSituations":"Pointing RubricMiddleware at an existing agent configured with a different response format; refactoring GraderResponse and leaving an old schema in place.","solutions":["Configure the grader with response_format=GraderResponse.","Return a plain dict matching GraderResponse fields — dicts are accepted and validated.","Log type(graded) to identify which schema the grader actually used.","Align any custom response model with GraderResponse or convert before returning."],"exampleFix":"// before\ngrader = create_agent(model, tools=[...], response_format=MyGrade)\n// after\nfrom deepagents.middleware.rubric import GraderResponse\ngrader = create_agent(model, tools=[...], response_format=GraderResponse)","handlingStrategy":"try-catch","validationCode":"raw = result.get(\"structured_response\")\nif raw is not None and not isinstance(raw, (GraderResponse, dict)):\n    raise TypeError(f\"expected GraderResponse or dict, got {type(raw).__name__}\")","typeGuard":"def is_valid_graded(v: object) -> TypeGuard[GraderResponse | dict]:\n    return isinstance(v, (GraderResponse, dict))","tryCatchPattern":"try:\n    graded = middleware._extract_graded(result)\nexcept TypeError as e:\n    if \"unexpected structured_response\" in str(e):\n        graded = GraderResponse.model_validate(result[\"structured_response\"].model_dump())\n    else:\n        raise","preventionTips":["Set the grader's response_format to GraderResponse, not a different model.","Return dicts from custom graders — they are auto-validated.","Keep GraderResponse imports in sync after refactors.","Log type(structured_response) when wiring new graders."],"tags":["python","rubric","structured-output","type-error"],"backgroundTag":"unexpected-response-type","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}