Skip to content

Rate limits, actionable errors, adapter fixes, onboarding nudges - #831

Merged
keysersoft merged 2 commits into
mainfrom
keysersoft/retry-after-actionable-errors
Oct 3, 2026
Merged

keysersoft merged 2 commits into
mainfrom
keysersoft/retry-after-actionable-errors

Conversation

@keysersoft

Copy link
Copy Markdown
Contributor

Block A of the connector/onboarding plan (analysis of the first 48 h after the Claude directory listing).

Rate limits (rest.engine.ts). A 429, or a 503 that carries Retry-After, gets at most one more attempt: after Retry-After when it is 3 s or less, after about a second when there is none, and none at all when the API asks for longer. Other transient errors keep the 300/900/2500 ms schedule. Retrying a 429 three times in 3.7 s turned one workspace's ~54k rejections into ~216k requests against an API that had asked for fewer. The model still gets the status and the retry-after header in the error.

Errors a person can act on

  • A missing variable (assertNoUnresolvedPlaceholders) and a never-authorized OAuth connector now include the connector's dashboard link (connectorPageUrl, from FRONTEND_URL), so Claude can hand it to the user.
  • A host that does not resolve reads "Host not found: 'x' could not be resolved (ENOTFOUND). Check the address…" instead of "SSRF guard: cannot resolve". It is still an SsrfBlockedError, and extractSsrfBlockedHostname reads both spellings, so the self-hosted allowlist hint keeps working.
  • New hints (error-hints.ts): Telegram 404/401 means a wrong bot token; "chat not found" and friends explain how a bot reaches a chat; Lexware's overdue cannot be combined with other statuses.

Adapters: Lexware list_vouchers marks voucherType and voucherStatus required and says overdue goes alone; api-football's healthPath typo is now healthcheckPath.

Onboarding drip (onboarding-cron.service.ts)

  • Reminders depend on the workspace having no connector (a teammate's connector counts), not on onboardingCompletedAt, which the Skip button on /welcome also sets.
  • A user who connected an AI client to an empty workspace gets the first reminder 2 h after connecting instead of 24 h after signing up, with copy that names the client ("Claude is connected. Now give it something to work with").
  • New server-only product event ai_client_connected (metadata.client), written when a client is connected for the first time.

Checked against production before opening this: the first cron run after deploy would send about 199 first reminders (142 of them to users who connected Claude to an empty workspace, 56 to users who had pressed Skip) and 2 second reminders. One-off; afterwards it is the normal flow.

Tests: retry policy (429 without/with short/long Retry-After, 503 with Retry-After, parseRetryAfterMs), link in the placeholder error, connectorPageUrl, the "Host not found" wording, Telegram/Lexware hints, the grant event (new vs re-grant) and four onboarding cases (AI client, waiting 24 h, after Skip, teammate's connector). Full backend suite passes locally (6412), typecheck and lint clean.

- REST engine: a 429 (or a 503 with Retry-After) gets at most one more
  attempt, after the API's Retry-After when it is 3 s or less, after ~1 s
  when there is none, and none when it asks for longer. Retrying 429s three
  times multiplied load on APIs that were already limiting us.
- Errors for a missing variable or a never-authorized OAuth connector link
  to the connector's page; a host that does not resolve is reported as
  'Host not found' instead of 'SSRF guard: cannot resolve'.
- Error hints for Telegram (wrong bot token, unreachable chat) and Lexware
  (overdue cannot be combined with other statuses); Lexware list_vouchers
  marks voucherType and voucherStatus required; api-football healthPath
  typo fixed.
- Onboarding drip: reminders depend on the workspace having no connector
  (a teammate's counts), not on the Skip flag of /welcome. A user who
  connected Claude/ChatGPT to an empty workspace gets the first nudge 2 h
  later, naming the client. New server-only event ai_client_connected.
@keysersoft
keysersoft merged commit 75633af into main Oct 3, 2026
13 checks passed
@keysersoft
keysersoft deleted the keysersoft/retry-after-actionable-errors branch October 3, 2026 11:54
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant