rohitg00/ai-engineering-from-scratch · error · ValueError

Messages API response must be an object

Error message

Messages API response must be an object

What it means

Raised in AnthropicMessagesHTTPTransport.create_message when the HTTP 200 response body decodes to something other than a JSON object. The Messages API contract requires a top-level object (content, stop_reason, usage), so a list, string, or scalar body means the response is not a valid Messages reply.

Solutions

  1. Confirm the endpoint actually serves the Messages API and is not returning a JSON array or plain text
  2. Check for intercepting proxies or gateways that rewrap responses
  3. Assert the response shape in tests with a fake transport returning a well-formed message object
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at certifications/claude/lessons/30-developer-application-capstone/code/main.py:68 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at certifications/claude/lessons/30-developer-application-capstone/code/main.py:68

    def create_message(self, payload: dict[str, Any]) -> dict[str, Any]:
        body = json.dumps(payload).encode("utf-8")
        request = urllib.request.Request(
            self.endpoint,
            data=body,
            method="POST",
            headers={
                "content-type": "application/json",
                "anthropic-version": ANTHROPIC_VERSION,
                "x-api-key": self._api_key,
            },
        )
        try:
            with self._opener(request, timeout=self.timeout_seconds) as response:
                decoded = json.loads(response.read().decode("utf-8"))
        except urllib.error.HTTPError as error:
            raise RuntimeError(f"Messages API returned HTTP {error.code}") from None
        if not isinstance(decoded, dict):
            raise ValueError("Messages API response must be an object")
        return decoded


def build_live_order_request(request: str, model: str) -> dict[str, Any]:
    """Build an inspectable wire payload with the same bounded lookup contract."""
    return {
        "model": model,
        "max_tokens": 128,
        "system": (
            "You are a bounded order-status router. Use lookup_order only when "
            "the user supplies an exact public order ID. Never claim execution."
        ),
        "messages": [{"role": "user", "content": request}],
        "tools": [
            {
                "name": "lookup_order",
                "description": "Read one visible order status. Never changes order state.",
                "input_schema": {

View on GitHub (pinned to 39ea8a1c6d)