package gateway import "testing" // The reason a 400 gives is the whole diagnosis, and it used to be thrown away. // // A deployment answered every single run with "The agent could not finish — // something it needed did not answer." Retrieval worked, the run was created, // the provider was reached, and the trajectory recorded `gateway.invalid_request` // and nothing else. The actual cause was one sentence long and Anthropic had // sent it: the account was out of credit. Nothing a client, a log or a run // detail could show said so, because `translate` dropped the body. // // The envelope below is the real one, copied from that response. func TestAnthropicErrorMessage(t *testing.T) { cases := []struct { name string raw string want string }{ { name: "the outage this test exists for", raw: `{"type":"error","error":{"type":"invalid_request_error",` + `"message":"Your credit balance is too low to access the Anthropic API. ` + `Please go to Plans & Billing to upgrade or purchase credits."},` + `"request_id":"req_011CeiJqr8rTdpbZYhcL6VHG"}`, want: "Your credit balance is too low to access the Anthropic API. " + "Please go to Plans & Billing to upgrade or purchase credits.", }, { name: "a message-less envelope falls back to the type", raw: `{"type":"error","error":{"type":"overloaded_error"}}`, want: "overloaded_error", }, // Best-effort by design: a failure to read a failure must not become a // second failure. {name: "unparseable body yields nothing", raw: `not json at all`, want: ""}, {name: "empty body yields nothing", raw: ``, want: ""}, } for _, c := range cases { if got := anthropicErrorMessage(c.raw); got != c.want { t.Errorf("%s: anthropicErrorMessage() = %q, want %q", c.name, got, c.want) } } }