{"record":{"id":"a691c97071e5e08d","repo":"rohitg00/ai-engineering-from-scratch","slug":"review-goal-content-must-be-an-object","errorCode":null,"errorMessage":"review_goal.content must be an object","messagePattern":"review_goal\\.content must be an object","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"certifications/claude/lessons/11-mcp-server-design-and-integration/code/main.py","lineNumber":415,"sourceCode":"        missing_responses = {\n            key: request for key, request in input_requests.items() if key not in responses\n        }\n        if missing_responses:\n            return self._input_required(\n                inputRequests=missing_responses, requestState=state\n            )\n\n        workspace_scope = responses[\"workspace_scope\"]\n        review_sample = responses[\"review_sample\"]\n        elicitation = responses[\"review_goal\"]\n        if not all(\n            isinstance(response, dict)\n            for response in (workspace_scope, review_sample, elicitation)\n        ):\n            raise ValueError(\"inputResponses entries must be objects\")\n        elicitation_content = elicitation.get(\"content\", {})\n        if not isinstance(elicitation_content, dict):\n            raise ValueError(\"review_goal.content must be an object\")\n        roots = workspace_scope.get(\"roots\")\n        sample_content = review_sample.get(\"content\", {})\n        goal = elicitation_content.get(\"goal\")\n        if not isinstance(roots, list) or not isinstance(sample_content, dict):\n            raise ValueError(\"inputResponses contain invalid roots or sampling results\")\n        if elicitation.get(\"action\") != \"accept\" or not isinstance(goal, str):\n            raise ValueError(\"review_goal must be accepted with a string goal\")\n        sample = sample_content.get(\"text\")\n        if not isinstance(sample, str):\n            raise ValueError(\"review_sample must contain text\")\n        summary = {\n            \"goal\": goal,\n            \"rootCount\": len(roots),\n            \"sample\": sample,\n            \"topic\": arguments[\"topic\"],\n        }\n        return self._complete(\n            content=[{\"type\": \"text\", \"text\": json.dumps(summary, sort_keys=True)}],","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/rohitg00/ai-engineering-from-scratch/blob/39ea8a1c6d0b61f071226eff7ede4d4105fed820/certifications/claude/lessons/11-mcp-server-design-and-integration/code/main.py#L397-L433","documentation":"Inside the review_goal elicitation response, content must be an object because it carries the form fields — here the 'goal' string. A string or list content, even a plausible one like the goal text itself, is rejected before goal extraction.","triggerScenarios":"Sending {\"action\": \"accept\", \"content\": \"review the auth flow\"} instead of {\"action\": \"accept\", \"content\": {\"goal\": \"review the auth flow\"}}.","commonSituations":"Elicitation form output flattened to a plain string by middleware; a client that models elicitation content like sampling text content; schema drift between the client form and the server's requestedSchema.","solutions":["Match the requestedSchema in the server's elicitation/create params — content is an object with a goal string field","Wrap free-text goals: content = {\"goal\": value}\"","Log the elicitation request's requestedSchema before building the response"],"exampleFix":"# before\nreview_goal = {\"action\": \"accept\", \"content\": \"check error handling\"}\n\n# after\nreview_goal = {\"action\": \"accept\", \"content\": {\"goal\": \"check error handling\"}}","handlingStrategy":"validation","validationCode":"content = elicitation_response.get(\"content\")\nif not isinstance(content, dict):\n    elicitation_response[\"content\"] = content = {}\nif not isinstance(content.get(\"goal\"), str):\n    raise ValueError(\"elicitation content must be an object with a string goal\")","typeGuard":"def is_form_content(content: object) -> bool:\n    return isinstance(content, dict) and isinstance(content.get(\"goal\"), str)","tryCatchPattern":null,"preventionTips":["Shape elicitation responses from the request's requestedSchema","Keep form fields as object keys, never flattened strings","Unit-test the response builder against the schema"],"tags":["mcp","elicitation","validation","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"39ea8a1c6d0b61f071226eff7ede4d4105fed820","analyzedAt":"2026-08-26T03:13:46.626Z","schemaVersion":2},"datasetVersion":"2026-08-26T07:17:17.940Z"}