From 943d3b0606045bc2c4328b00eeb3aecfb11ce89b Mon Sep 17 00:00:00 2001 From: David Gageot Date: Thu, 12 Mar 2026 17:17:54 +0100 Subject: [PATCH] This can be retried Signed-off-by: David Gageot --- pkg/modelerrors/modelerrors.go | 1 + pkg/modelerrors/modelerrors_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/pkg/modelerrors/modelerrors.go b/pkg/modelerrors/modelerrors.go index 713920e4e..3efd4d705 100644 --- a/pkg/modelerrors/modelerrors.go +++ b/pkg/modelerrors/modelerrors.go @@ -256,6 +256,7 @@ func IsRetryableModelError(err error) bool { "fetch failed", // Network fetch failure "reset before headers", // Connection reset before headers received "upstream connect", // Upstream connection error + "internal_error", // HTTP/2 INTERNAL_ERROR (stream-level) } for _, pattern := range retryablePatterns { diff --git a/pkg/modelerrors/modelerrors_test.go b/pkg/modelerrors/modelerrors_test.go index 3eb119b20..056a30755 100644 --- a/pkg/modelerrors/modelerrors_test.go +++ b/pkg/modelerrors/modelerrors_test.go @@ -54,6 +54,7 @@ func TestIsRetryableModelError(t *testing.T) { {name: "fetch failed", err: errors.New("fetch failed"), expected: true}, {name: "reset before headers", err: errors.New("reset before headers"), expected: true}, {name: "upstream connect error", err: errors.New("upstream connect error"), expected: true}, + {name: "HTTP/2 INTERNAL_ERROR", err: fmt.Errorf("error receiving from stream: %w", errors.New("stream error: stream ID 1; INTERNAL_ERROR; received from peer")), expected: true}, {name: "context overflow - prompt too long", err: errors.New("prompt is too long: 226360 tokens > 200000 maximum"), expected: false}, {name: "context overflow - thinking budget", err: errors.New("max_tokens must be greater than thinking.budget_tokens"), expected: false}, {name: "context overflow - wrapped", err: &ContextOverflowError{Underlying: errors.New("test")}, expected: false},