Skip to content

fix(session): retry on 5xx errors from non-standard provider error types#19204

Open
okuyam2y wants to merge 1 commit intoanomalyco:devfrom
okuyam2y:fix/5xx-retry-error-variants
Open

fix(session): retry on 5xx errors from non-standard provider error types#19204
okuyam2y wants to merge 1 commit intoanomalyco:devfrom
okuyam2y:fix/5xx-retry-error-variants

Conversation

@okuyam2y
Copy link
Copy Markdown

@okuyam2y okuyam2y commented Mar 26, 2026

Issue for this PR

Closes #19203

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

MessageV2.fromError only upgrades APICallError instances to retryable APIError. When an OpenAI-compatible provider throws a plain Error or object with HTTP status fields instead, the error falls through to NamedError.Unknown and session retry never runs.

This adds a fallback status extractor for non-APICallError inputs and classifies 5xx responses as retryable APIError. Covered shapes: top-level status/statusCode, nested response.status/response.statusCode, JSON-encoded error messages carrying those fields (with inner message extraction), and plain objects with the same properties.

A file-local ErrorWithStatus interface is used instead of as any casts, following the existing FetchDecompressionError pattern. 4xx handling is unchanged.

How did you verify your code works?

  • 8 new unit tests in message-v2.test.ts covering all extraction paths and negative cases (4xx, no status)
  • All 30 message-v2 tests and 19 retry tests pass
  • bun typecheck passes across all packages

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions bot added the needs:compliance This means the issue will auto-close after 2 hours. label Mar 26, 2026
@github-actions
Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Potential Related PRs

Found 2 related PRs that address similar retry logic issues:

  1. PR fix(retry): retry transient 429 responses even when provider marks non-retryable #18443 - fix(retry): retry transient 429 responses even when provider marks non-retryable

  2. PR fix: retry on AI_TypeValidationError from provider 5xx responses #16228 - fix: retry on AI_TypeValidationError from provider 5xx responses

These PRs are not exact duplicates but address the same general area (session/retry error handling for provider responses). You may want to review them for potential conflicts or ensure consistency in the retry logic approach.

@github-actions github-actions bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Mar 26, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

…ypes

Some API gateways throw non-APICallError errors with status codes in
varying shapes (error.status, error.statusCode, error.response.status,
or JSON-encoded in error.message). These were not being detected,
causing 5xx errors to be classified as UnknownError instead of
retryable APIError.

Add ErrorWithStatus interface and multi-path status code extraction
to the Error case in fromError(), with JSON message fallback.
@okuyam2y okuyam2y force-pushed the fix/5xx-retry-error-variants branch from 4be2e20 to dbb61ba Compare April 6, 2026 14:20
@okuyam2y
Copy link
Copy Markdown
Author

okuyam2y commented Apr 6, 2026

Rebased onto latest dev and squashed into a single commit. All 28 message-v2 tests pass, typecheck clean.

Changes from previous version:

  • Adapted to upstream's errorMessage() helper (added in recent commits)
  • Squashed 3 commits into 1 for cleaner history

Would appreciate a review when you get a chance. Happy to address any feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: 5xx errors from non-standard providers are not retried

1 participant