fix(coderd/x/chatd/chaterror): classify aibridge 403 as ChatErrorKindUsageLimit (#27538)

Adds the string `ai budget` to the classifier for
`ChatErrorKindUsageLimit`.

<img width="809" height="267" alt="Screenshot 2026-07-27 at 18 27 13"
src="https://github.com/user-attachments/assets/7e2ba9ae-8168-4fd4-87f6-c4e7dfdc9526"
/>

Testing notes:
- I set the group limit by running `insert into group_ai_budgets values
('<everyone group UUID>', 1, NOW(), NOW());`


> Created by a human, trimmed down by a Coder agent.

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Cian Johnston
2026-07-27 17:54:56 +00:00
committed by GitHub
co-authored by Copilot Autofix powered by AI
parent 95be28850d
commit daf655dff8
2 changed files with 3 additions and 1 deletions
@@ -503,6 +503,8 @@ func TestClassify_PatternCoverage(t *testing.T) {
{name: "QuotaLiteral", err: "quota", wantKind: codersdk.ChatErrorKindUsageLimit, wantRetry: false},
{name: "BillingLiteral", err: "billing", wantKind: codersdk.ChatErrorKindUsageLimit, wantRetry: false},
{name: "InsufficientQuotaLiteral", err: "insufficient_quota", wantKind: codersdk.ChatErrorKindUsageLimit, wantRetry: false},
{name: "AIBudgetExceededLiteral", err: "status 403: AI budget of US$10.00 exceeded", wantKind: codersdk.ChatErrorKindUsageLimit, wantRetry: false},
{name: "AIBudgetCheckFailedLiteral", err: "status 500: internal server error checking user AI budget", wantKind: codersdk.ChatErrorKindGeneric, wantRetry: true},
{name: "PaymentRequiredLiteral", err: "payment required", wantKind: codersdk.ChatErrorKindUsageLimit, wantRetry: false},
{name: "ForbiddenLiteral", err: "forbidden", wantKind: codersdk.ChatErrorKindAuth, wantRetry: false},
{name: "InvalidModelLiteral", err: "invalid model", wantKind: codersdk.ChatErrorKindConfig, wantRetry: false},
+1 -1
View File
@@ -73,7 +73,7 @@ var (
}
// Hard usage exhaustion codes that fire at any HTTP status,
// including 429.
usageLimitAnyStatusPatterns = []string{"insufficient_quota"}
usageLimitAnyStatusPatterns = []string{"insufficient_quota", "ai budget of"}
configPatterns = []string{
"invalid model",
"model not found",