workers-ai-provider: Workers AI rate-limit error 3021 is classified as non-retryable
- Dominant language
- TypeScript
- Stars
- 1.2k
- Forks
- 345
- Avg merge
- 13h 31m
- Merged PRs (30d)
- 1
Description
# Workers AI binding error 3021 is treated as non-retryable despite HTTP 429
`workers-ai-provider@4.0.0` does not recognize Workers AI inference RPM-limit code `3021`. The native binding throws `Error("3021: rate limiting: inference request per min rate reached")`. `normalizeBindingError` constructs an `APICallError` without `statusCode`, with `isRetryable: false`, so native AI SDK retries stop immediately.
The corresponding stored Workers AI Gateway response was HTTP 429 with `httpCode: 429`, `internalCode: 3021`, `name: "AiError"`, and the same description. No customer identifiers or private prompts are included here.
## Reproduction
```js
import { createWorkersAI } from "workers-ai-provider";
const model = createWorkersAI({
binding: {
run: async () => {
throw new Error("3021: rate limiting: inference request per min rate reached");
},
},
})("@cf/zai-org/glm-5.3-flash");
try {
await model.doStream({
prompt: [{ role: "user", content: [{ type: "text", text: "Welcome" }] }],
});
} catch (error) {
console.log(error.statusCode, error.isRetryable);
// Actual: undefined, false. Expected: 429, true.
}
```
## Proposed correction
Add `3021: 429` to `WORKERS_AI_ERROR_CODE_TO_STATUS` in `packages/gateway-core/src/workers-ai-errors.ts`. This also lets the existing parser recognize the error code. No custom retry loop is required.
## Validation
An isolated copy of the released package fails four rate-limit tests before the correction and passes all seven tests after it:
- Streaming and non-streaming binding errors retain their cause and map to retryable HTTP 429.
- Native AI SDK `streamText` and `generateText` each recover after two simulated 3021 errors, using the SDK's existing increasing delays (approximately 2 and 4 seconds).
- Invalid input, unknown errors, and cancellation do not retry.
This is controlled local validation, not a production load test. The numeric model/account RPM limit is not established by this report.
Contributor guide
Research direction
Start in packages/gateway-core/src/workers-ai-errors.ts and inspect WORKERS_AI_ERROR_CODE_TO_STATUS together with normalizeBindingError. Exercise the binding run path with the supplied 3021 error, then verify streaming and non-streaming binding errors and native AI SDK streamText and generateText retry as HTTP 429 while invalid input, unknown errors, and cancellation remain non-retrying.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 92/100