From 91d79ce1205d56abf1fbee95e15200ceb809dd6f Mon Sep 17 00:00:00 2001 From: viettranx Date: Sat, 18 Apr 2026 14:42:17 +0700 Subject: [PATCH] fix(providers): capture claude-cli stream errors and surface real message (#884) claude-cli emits API errors (rate limits, usage limits) via stream-json stdout result events, not stderr. Previous code only checked ev.Subtype == "error" and used an empty stderr buffer in the final wrap, so users saw a generic "something went wrong" instead of the real cause. - Add IsError and Error fields to cliStreamEvent to parse both signals - Capture stream error message when FinishReason flips to "error" - Substitute captured message when stderr is empty in cmd.Wait path - Extend gateway rate-limit classifier to recognize "usage limit" --- cmd/gateway_errors.go | 2 +- internal/providers/claude_cli_types.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/gateway_errors.go b/cmd/gateway_errors.go index 61dde32b..76b676bc 100644 --- a/cmd/gateway_errors.go +++ b/cmd/gateway_errors.go @@ -32,7 +32,7 @@ func formatAgentError(err error) string { } // 4. Rate limit - if containsAny(lower, "rate limit", "rate_limit", "too many requests", "429", "quota exceeded", "resource_exhausted") { + if containsAny(lower, "rate limit", "rate_limit", "too many requests", "429", "quota exceeded", "resource_exhausted", "usage limit") { return "⚠️ API rate limit reached. Please try again later." } diff --git a/internal/providers/claude_cli_types.go b/internal/providers/claude_cli_types.go index b56a4dd9..d2838028 100644 --- a/internal/providers/claude_cli_types.go +++ b/internal/providers/claude_cli_types.go @@ -29,6 +29,8 @@ type cliStreamEvent struct { Model string `json:"model,omitempty"` CostUSD float64 `json:"cost_usd,omitempty"` Usage *cliUsage `json:"usage,omitempty"` + IsError bool `json:"is_error,omitempty"` // true when subtype="error" + Error string `json:"error,omitempty"` // error message (may be set when result is empty) } // cliStreamMsg wraps content blocks inside an assistant message event.