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

  1. 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
  2. Validate the inputResponses shape before resuming the call
  3. 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

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


AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26). Data as JSON: /api/errors/94309f3e4ccf80fc. Report an issue: GitHub.