micro/go-micro · error

failed to parse response: %w

Error message

failed to parse response: %w

What it means

callAPI received HTTP 200 from Together but the body could not be decoded into the expected chat-completions shape ({choices:[{message:{content,tool_calls}}]}). json.Unmarshal failed, so the response was malformed or structurally unexpected. The underlying *json.UnmarshalTypeError / *json.SyntaxError is wrapped with %w.

Source

Thrown at ai/together/together.go:200

	}

	var chatResp struct {
		Choices []struct {
			Message struct {
				Content   string `json:"content"`
				ToolCalls []struct {
					ID       string `json:"id"`
					Function struct {
						Name      string `json:"name"`
						Arguments string `json:"arguments"`
					} `json:"function"`
				} `json:"tool_calls"`
			} `json:"message"`
		} `json:"choices"`
	}

	if err := json.Unmarshal(respBody, &chatResp); err != nil {
		return nil, nil, fmt.Errorf("failed to parse response: %w", err)
	}
	if len(chatResp.Choices) == 0 {
		return nil, nil, fmt.Errorf("no response from API")
	}

	choice := chatResp.Choices[0]
	response := &ai.Response{Reply: choice.Message.Content}

	for _, tc := range choice.Message.ToolCalls {
		var input map[string]any
		if err := json.Unmarshal([]byte(tc.Function.Arguments), &input); err != nil {
			input = map[string]any{}
		}
		response.ToolCalls = append(response.ToolCalls, ai.ToolCall{
			ID:    tc.ID,
			Name:  tc.Function.Name,
			Input: input,
		})

View on GitHub (pinned to 24529f1404)

Solutions

  1. Log respBody on this error to see what was actually returned
  2. Verify BaseURL points to the real Together API (or a gateway with an identical chat-completions schema)
  3. Check for API version changes and pin the endpoint path /v1/chat/completions
  4. Use errors.As(err, &json.UnmarshalTypeError) to identify the exact mismatched field

Example fix

// before
resp, err := p.Generate(ctx, req)
// after
resp, err := p.Generate(ctx, req)
if err != nil && strings.Contains(err.Error(), "failed to parse response") {
    log.Printf("unexpected Together response body, check BaseURL/gateway")
}
Defensive patterns

Strategy: validation

Type guard

func validChoices(b []byte) bool {
    var v struct { Choices []json.RawMessage `json:"choices"` }
    return json.Unmarshal(b, &v) == nil && len(v.Choices) > 0
}

Try / catch

resp, err := p.Generate(ctx, req)
if err != nil {
    var jsonErr *json.UnmarshalTypeError
    if errors.As(err, &jsonErr) {
        log.Printf("schema mismatch at field %s", jsonErr.Field)
    }
}

Prevention

When it happens

Trigger: The API returns 200 with HTML/error text, an unexpected JSON schema (e.g. missing or mistyped fields like choices not being an array), or a truncated body.

Common situations: BaseURL pointed at a compatible-but-different gateway that returns a different schema; a proxy/CDN injecting an HTML error page with status 200; API version drift changing the response shape.

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 micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/65978d253a0cf431. Report an issue: GitHub.