rohitg00/ai-engineering-from-scratch · error · ValueError
inputResponses entries must be objects
Error message
inputResponses entries must be objects
What it means
On the second round of prepare_review the server unpacks inputResponses['workspace_scope'], ['review_sample'], and ['review_goal']. Each must be a JSON object; any string, number, list, or null entry raises this before any field extraction happens.
Source
Thrown at certifications/claude/lessons/11-mcp-server-design-and-integration/code/main.py:412
self.state_signer.verify(state, "tools/call", "prepare_review", arguments)
if not isinstance(responses, dict):
return self._input_required(inputRequests=input_requests, requestState=state)
missing_responses = {
key: request for key, request in input_requests.items() if key not in responses
}
if missing_responses:
return self._input_required(
inputRequests=missing_responses, requestState=state
)
workspace_scope = responses["workspace_scope"]
review_sample = responses["review_sample"]
elicitation = responses["review_goal"]
if not all(
isinstance(response, dict)
for response in (workspace_scope, review_sample, elicitation)
):
raise ValueError("inputResponses entries must be objects")
elicitation_content = elicitation.get("content", {})
if not isinstance(elicitation_content, dict):
raise ValueError("review_goal.content must be an object")
roots = workspace_scope.get("roots")
sample_content = review_sample.get("content", {})
goal = elicitation_content.get("goal")
if not isinstance(roots, list) or not isinstance(sample_content, dict):
raise ValueError("inputResponses contain invalid roots or sampling results")
if elicitation.get("action") != "accept" or not isinstance(goal, str):
raise ValueError("review_goal must be accepted with a string goal")
sample = sample_content.get("text")
if not isinstance(sample, str):
raise ValueError("review_sample must contain text")
summary = {
"goal": goal,
"rootCount": len(roots),
"sample": sample,
"topic": arguments["topic"],View on GitHub (pinned to 39ea8a1c6d)
Solutions
- Wrap each entry as an object: a roots/list result for workspace_scope, a createMessage result for review_sample, an elicitation result for review_goal
- Validate the inputResponses shape before resuming the call
- Derive responses from the server's inputRequests descriptors rather than hand-writing them
Example fix
# before
responses = {"workspace_scope": "file:///repo"}
# after
responses = {"workspace_scope": {"roots": []}} Defensive patterns
Strategy: validation
Validate before calling
for key in ("workspace_scope", "review_sample", "review_goal"):
entry = responses.get(key)
if not isinstance(entry, dict):
raise ValueError(f"inputResponses[{key!r}] must be an object")
server.exchange("tools/call", {"requestState": state, "inputResponses": responses}, metadata=meta) Type guard
def are_object_responses(responses: object) -> bool:
return isinstance(responses, dict) and all(
isinstance(responses.get(k), dict)
for k in ("workspace_scope", "review_sample", "review_goal")
) Prevention
- Build each response by executing the corresponding inputRequest, not by hand
- Never substitute a URI string or list for a response object
- Validate the whole inputResponses map before resuming the call
When it happens
Trigger: Resuming tools/call with requestState plus inputResponses like {"workspace_scope": "file:///repo", "review_sample": [...], "review_goal": null}.
Common situations: Client stores the raw roots URI string instead of a roots/list response object; partial serialization drops a response to null; replaying hand-written fixtures that do not match MCP response shapes.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- review_goal.content must be an object
- review_goal must be accepted with a string goal
- -32600
- -32603
- _meta.{PROTOCOL_VERSION_KEY} is required
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/94309f3e4ccf80fc.
Report an issue: GitHub.