micro/go-micro · error

failed to parse response: %w

Error message

failed to parse response: %w

What it means

Returned by Provider.callAPI when the 200 OK response body cannot be unmarshaled into the expected Anthropic response schema. The body was read successfully but its JSON shape doesn't match the struct (content array, stop_reason, etc.), indicating a schema/version mismatch or a non-Anthropic response.

Source

Thrown at ai/anthropic/anthropic.go:400

	}
	if httpResp.StatusCode != http.StatusOK {
		return nil, nil, ai.NewHTTPError(httpResp, respBody)
	}

	// Parse response
	var anthropicResp struct {
		Content []struct {
			Type  string          `json:"type"`
			Text  string          `json:"text"`
			ID    string          `json:"id"`
			Name  string          `json:"name"`
			Input json.RawMessage `json:"input"`
		} `json:"content"`
		StopReason string `json:"stop_reason"`
	}

	if err := json.Unmarshal(respBody, &anthropicResp); err != nil {
		return nil, nil, fmt.Errorf("failed to parse response: %w", err)
	}

	response := &ai.Response{StopReason: anthropicResp.StopReason}

	// Extract text reply
	var replyParts []string
	for _, block := range anthropicResp.Content {
		if block.Type == "text" && block.Text != "" {
			replyParts = append(replyParts, block.Text)
		}
	}
	if len(replyParts) > 0 {
		response.Reply = strings.Join(replyParts, "\n")
	}

	// Extract tool calls
	for _, block := range anthropicResp.Content {
		if block.Type == "tool_use" {

View on GitHub (pinned to 24529f1404)

Solutions

  1. Log respBody on failure to see the actual payload shape returned.
  2. Confirm the configured anthropic-version matches what your BaseURL endpoint actually serves; try pinning "2023-06-01".
  3. If using a proxy/gateway, verify it forwards Anthropic-format /v1/messages responses, not OpenAI-format ones.
  4. Update the library to a version whose response struct matches your API version.

Example fix

// before
anthropic.New(anthropic.WithBaseURL("https://openai-proxy.internal")) // serves OpenAI schema
// after
anthropic.New(anthropic.WithBaseURL("https://anthropic-compatible-gateway.internal"))
Defensive patterns

Strategy: validation

Validate before calling

func looksAnthropicCompatible(base string) error {
	// issue a minimal well-formed probe request and assert the response shape
	// contains keys "content" and "stop_reason" before switching providers
	return probeV1Messages(base)
}

Type guard

func isSchemaErr(err error) bool {
	var syn *json.SyntaxError
	var te *json.UnmarshalTypeError
	return err != nil && (errors.As(err, &syn) || errors.As(err, &te)) && strings.Contains(err.Error(), "failed to parse response")
}

Try / catch

resp, err := provider.Generate(ctx, prompt)
if err != nil && isSchemaErr(err) {
	log.Printf("unexpected response schema — check anthropic-version and gateway compatibility")
}

Prevention

When it happens

Trigger: json.Unmarshal of respBody fails: endpoint behind BaseURL returns a different JSON shape (OpenAI-compatible proxy, gateway error JSON), Anthropic changes the response schema under a different anthropic-version, or the body is truncated HTML/JSON.

Common situations: Pointing BaseURL at an OpenAI-format proxy whose /v1/messages isn't Anthropic-shaped, pinning an old/new anthropic-version whose schema differs, or a captive portal returning HTML with 200.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/790e22bd8b94d676. Report an issue: GitHub.