fix(coderd/x/chatd): show correct provider and clean detail for Bedrock errors (#26338)

## Problem
Bedrock errors (routed through aibridge) showed the wrong provider
("Anthropic ...")
and a doubly-wrapped detail string instead of the clean message.

## Fix (chatd only)
- **Provider label:** thread the configured provider to error
classification via
`GenerateAssistantOptions.ErrorProvider`. Transport provider still
drives prompt
  prep, sanitization, and metric labels (unchanged).
- **Detail:** unwrap the SDK transport wrapper (`METHOD "URL": NNN
{body}`) to surface
the inner message; handles top-level `{"message":...}` and nested
`{"error":{"message":...}}`.

## Notes
- Surfacing a top-level `message` now applies to all providers
(intentional; nested wins when both present).
- The advisor path keeps the transport label; accepted as-is (it returns
`err.Error()`, not the classification).
- Fixes display in chatd only; the wrapper originates in aibridge (out
of scope here).

🤖 Generated by Coder Agents.
This commit is contained in:
Cian Johnston
2026-06-16 11:14:37 +01:00
committed by GitHub
parent 12d7ad6100
commit 21a2652343
7 changed files with 293 additions and 34 deletions
@@ -171,6 +171,33 @@ func TestGenerateAssistant_ProviderContextSurvivesStreamError(t *testing.T) {
require.Equal(t, "OpenAI returned an unexpected error.", classified.Message)
}
func TestGenerateAssistant_ErrorProviderOverridesTransportLabel(t *testing.T) {
t.Parallel()
// Bedrock routed through aibridge uses the Anthropic transport, so
// Model.Provider() reports "anthropic". The user-facing error must use
// the configured provider from ErrorProvider instead.
model := &chattest.FakeModel{
ProviderName: "anthropic",
ModelName: "qwen3-coder-next",
StreamFn: func(_ context.Context, _ fantasy.Call) (fantasy.StreamResponse, error) {
return nil, xerrors.New("upstream returned status 400")
},
}
_, err := GenerateAssistant(context.Background(), GenerateAssistantOptions{
Model: model,
ErrorProvider: "bedrock",
Messages: []fantasy.Message{
textMessage(fantasy.MessageRoleUser, "hello"),
},
})
require.Error(t, err)
classified := chaterror.Classify(err)
require.Equal(t, "bedrock", classified.Provider)
require.Equal(t, "AWS Bedrock returned an unexpected error.", classified.Message)
}
func TestGenerateAssistant_HTTP2TransportErrorClassifiedAsRetryableTimeout(t *testing.T) {
t.Parallel()