You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
| 402 |`"Out of credits. Please add credits at https://codebuff.com/usage. Your free credits reset in 3 hours."`|
26
26
27
27
### Typed errors (error code + message)
28
28
@@ -32,11 +32,13 @@ Used for:
32
32
33
33
Used for errors that the client needs to identify programmatically:
34
34
35
-
| Status |`error` code | Example `message`|
36
-
|--------|-------------|-------------------|
37
-
| 403 |`account_suspended`|`"Your account has been suspended. Please contact support@codebuff.com if you did not expect this."`|
38
-
| 403 |`free_mode_unavailable`|`"Free mode is not available in your country."` (Freebuff: `"Freebuff is not available in your country."`) |
39
-
| 429 |`rate_limit_exceeded`|`"Subscription weekly limit reached. Your limit resets in 2 hours. Enable 'Continue with credits' in the CLI to use a-la-carte credits."`|
| 403 |`account_suspended`|`"Your account has been suspended. Please contact support@codebuff.com if you did not expect this."`|
38
+
| 403 |`free_mode_unavailable`|`"Free mode is not available in your country."` (Freebuff: `"Freebuff is not available in your country."`) |
39
+
| 409 |`session_superseded`|`"Another instance of freebuff has taken over this session. Only one instance per account is allowed."`|
40
+
| 409 |`session_model_mismatch`|`"This session is bound to <model>; restart freebuff to switch models."`|
41
+
| 429 |`rate_limit_exceeded`|`"Subscription weekly limit reached. Your limit resets in 2 hours. Enable 'Continue with credits' in the CLI to use a-la-carte credits."`|
40
42
41
43
### Catch-all server error
42
44
@@ -65,20 +67,38 @@ AI SDK creates: APICallError {
65
67
}
66
68
```
67
69
68
-
The server's human-readable `message` and machine-readable `error` code are buried inside `responseBody` as a JSON string. The `APICallError.message` is just the HTTP status text ("Forbidden", "Payment Required", etc.).
70
+
The server's human-readable `message` and machine-readable `error` code are buried inside `responseBody` as a JSON string. The `APICallError.message` is often just the HTTP status text ("Forbidden", "Payment Required", "Conflict", etc.).
71
+
72
+
Some statuses that the AI SDK considers retryable, including HTTP 409, can be retried and then wrapped in an `AI_RetryError`:
73
+
74
+
```
75
+
AI_RetryError {
76
+
message: "Failed after 4 attempts. Last error: Conflict",
`extractApiErrorDetails()` checks the top-level error and nested retry wrapper fields (`lastError`, `errors`, and `cause`). For each candidate it extracts `statusCode`/`status` and parses any API `responseBody` with `parseApiErrorResponseBody()`.
100
+
101
+
This helper is called in two places:
82
102
83
103
### 1. Agent Runtime catch block
84
104
@@ -88,18 +108,17 @@ This is the **primary** error handler. Most API errors are caught here because t
// apiErrorDetails.message = 'Free mode is not available in your country.'
114
+
// apiErrorDetails.statusCode = 403
96
115
// ...
97
116
return {
98
117
output: {
99
118
type: 'error',
100
119
message: hasServerMessage?errorMessage:'Agent run error: '+errorMessage,
101
-
statusCode,
102
-
error: errorCode, // ← machine-readable code for client matching
120
+
statusCode: apiErrorDetails.statusCode,
121
+
error: apiErrorDetails.errorCode, // ← machine-readable code for client matching
103
122
},
104
123
}
105
124
}
@@ -111,6 +130,8 @@ catch (error) {
111
130
112
131
This is a **fallback** handler for errors that escape the agent runtime (e.g., errors during setup before the agent loop starts).
113
132
133
+
It also calls `extractApiErrorDetails()` so retry-wrapped setup errors preserve the same `statusCode`, `error`, and `message` fields as agent-loop errors.
@@ -210,4 +234,4 @@ To add a new error type that the CLI can identify and handle specially:
210
234
}
211
235
```
212
236
213
-
No changes needed in the agent runtime or SDK — `parseApiErrorResponseBody` automatically extracts any `error` and `message` fields from the server's response body.
237
+
No changes needed in the agent runtime or SDK — `extractApiErrorDetails()` automatically extracts any `error` and `message` fields from the server's response body, including when the API error is nested inside an AI SDK retry wrapper.
0 commit comments