Skip to content

InsufficientBalanceError for 403 INSUFFICIENT_BALANCE; free plan 401 docs - #45

Closed
quantumdark wants to merge 6 commits into
developmentfrom
feat/235-insufficient-balance
Closed

quantumdark wants to merge 6 commits into
developmentfrom
feat/235-insufficient-balance

Conversation

@quantumdark

@quantumdark quantumdark commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Raises InsufficientBalanceError for a 403 INSUFFICIENT_BALANCE (reports what fits / max_affordable_records), and documents the free plan and the no-credentials 401 object (signup_url kept).

Ships with the #235 platform main release (discolike-platform !993 → !996). Release the SDK after the platform rollout.

RetriggerConfidence Score: 4/5

The code appears safe to merge, with two non-blocking documentation corrections.

Fix All in Claude CodeFindings

  1. P2 Retry advice misses zero ▶
  2. P2 SDK change is denied ▶
Fix with agent prompt
### Issue 1
README.md:373
`max_affordable_records` is not always a size that fits. The new exception documentation says it can be `0` when even the request fee exceeds the balance. Single-company and single-email requests also cannot be made smaller. A caller following this advice could retry with zero records and get another error.

Qualify the advice here and in `CHANGELOG.md`: retry smaller only when the request supports it and the value is positive; otherwise top up.

### Issue 2
CHANGELOG.md:5
The claim “No SDK code change” contradicts this PR. `_extract_message` gains the object-`detail` branch that makes `AuthenticationError` use the server's `message`; older versions fall back to the JSON body. Remove that claim so readers know the readable message requires the updated SDK.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds InsufficientBalanceError for 403 responses carrying INSUFFICIENT_BALANCE, while keeping it catchable as PlanAccessError.

  • The SDK and CLI show callers how much of a request fits the balance.
  • SDK errors use the message inside structured API details.

Reviews (1) · Last reviewed commit: "docs(sdk): max_affordable_records is 0 w..." · Reviewed by Greptile

Comment thread README.md
```

`AuthenticationError`, `PlanAccessError`, `NotFoundError`, `ServerError`, and `APIConnectionError` cover the rest. Transient failures are retried automatically (3 attempts by default).
`AuthenticationError`, `PlanAccessError`, `NotFoundError`, `ServerError`, and `APIConnectionError` cover the rest. A request the account's remaining balance cannot cover raises `InsufficientBalanceError` (a `PlanAccessError`), whose `max_affordable_records` is the largest size that would fit, counted in the request's own unit (the message names it: records, contacts, domains, rows, queries or personas). Transient failures are retried automatically (3 attempts by default).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Retry advice misses zero

max_affordable_records is not always a size that fits. The new exception documentation says it can be 0 when even the request fee exceeds the balance. Single-company and single-email requests also cannot be made smaller. A caller following this advice could retry with zero records and get another error.

Qualify the advice here and in CHANGELOG.md: retry smaller only when the request supports it and the value is positive; otherwise top up.

Prompt To Fix With AI
This is a comment left during a code review.
Path: README.md
Line: 373

Comment:
**Retry advice misses zero**

`max_affordable_records` is not always a size that fits. The new exception documentation says it can be `0` when even the request fee exceeds the balance. Single-company and single-email requests also cannot be made smaller. A caller following this advice could retry with zero records and get another error.

Qualify the advice here and in `CHANGELOG.md`: retry smaller only when the request supports it and the value is positive; otherwise top up.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

Comment thread CHANGELOG.md

## Unreleased

- SDK/CLI: new accounts start on the free plan ($5.00 of usage a month at pay-as-you-go rates, no card), and a request with no credentials now gets a 401 whose `detail` is an object (`code: "UNAUTHENTICATED"`, `message`, `signup_url`, `plan`, `allowance_usd`, `cpc`, `cpm`) pointing at free signup. The SDK raises `AuthenticationError` with the server's `message`, as for any object `detail`; other 401s keep a string `detail`. No SDK code change; older versions show the JSON body as the message.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 SDK change is denied

The claim “No SDK code change” contradicts this PR. _extract_message gains the object-detail branch that makes AuthenticationError use the server's message; older versions fall back to the JSON body. Remove that claim so readers know the readable message requires the updated SDK.

Prompt To Fix With AI
This is a comment left during a code review.
Path: CHANGELOG.md
Line: 5

Comment:
**SDK change is denied**

The claim “No SDK code change” contradicts this PR. `_extract_message` gains the object-`detail` branch that makes `AuthenticationError` use the server's `message`; older versions fall back to the JSON body. Remove that claim so readers know the readable message requires the updated SDK.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code Fix in Codex

@yudelevi

Copy link
Copy Markdown
Contributor

Split into #47 (InsufficientBalanceError for the live 403, platform !994 is on main) and #48 (free plan + no-credentials 401, stacked, waits for platform !995/!996). Same commits, cherry-picked onto current development.

@yudelevi yudelevi closed this Oct 19, 2026
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.

2 participants