Skip to content

[Go SDK] AI client flattens structured error responses into fmt.Errorf #436

@santoshkumarradha

Description

@santoshkumarradha

Summary

The Go SDK AI client collapses all API error responses into a plain fmt.Errorf string, discarding the HTTP status code and structured error fields that callers need for retry and fallback logic.

Context

client.go:132 in sdk/go/ai handles non-2xx responses by parsing an ErrorResponse struct and then returning fmt.Errorf("API error: %s", errResp.Error.Message). The HTTP status code, provider error type, and error code fields are all discarded. Callers cannot distinguish a 401 (rotate credentials) from a 429 (back off and retry) from a 400 content-filter rejection from a 500 server error. The Python SDK's equivalent raises a typed exception hierarchy. Agent code built on the Go SDK must either hardcode string matching on error messages or treat all AI errors identically.

Scope

In Scope

  • Define a *APIError struct with StatusCode int, Message string, Type string, Code string, and a Body []byte field for unparseable responses.
  • Return *APIError from doRequest on any non-2xx response.
  • Implement Error() string on *APIError that formats a human-readable string including the status code.
  • Implement errors.Is / errors.As support so callers can check for specific status codes without type-asserting.

Out of Scope

  • Changing the retry logic — callers are responsible for retry decisions based on the error type.
  • Mapping every provider error code to a Go constant — Type and Code as strings are sufficient for v1.
  • Changing the request serialization or response parsing for successful responses.

Files

  • sdk/go/ai/client.go:132 — return *APIError instead of fmt.Errorf on non-2xx responses
  • sdk/go/ai/errors.go (new file) — define APIError struct and Error() / Is() / As() methods
  • sdk/go/ai/client_test.go — tests: 401 response returns *APIError with StatusCode == 401; 429 returns *APIError with StatusCode == 429; errors.As(err, &apiErr) works

Acceptance Criteria

  • Non-2xx AI API responses return a *APIError with the correct StatusCode
  • errors.As(err, &(*APIError)(nil)) works for all AI client errors
  • err.Error() includes the status code in human-readable form
  • Existing AI client tests continue to pass
  • Tests pass (go test ./sdk/go/...)
  • Linting passes (make lint)

Notes for Contributors

Severity: MEDIUM

Look at how the Python SDK structures its exception hierarchy in sdk/python/agentfield/ai/ for inspiration on what fields matter most to callers. The Body []byte fallback is important for cases where the provider returns a non-standard error body (e.g. an HTML 502 from a proxy) — store up to 4KB of the raw body to aid debugging.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:aiAI/LLM integrationbugSomething isn't workingenhancementNew feature or requestsdk:goGo SDK related

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions