Skip to content

language_models_cloud: Classify LLM token failures as provider rejections - #64754

Merged
ConradIrwin merged 1 commit into
mainfrom
typed-llm-token-errors
Sep 28, 2026
Merged

ConradIrwin merged 1 commit into
mainfrom
typed-llm-token-errors

Conversation

@ConradIrwin

Copy link
Copy Markdown
Member

CloudLlmTokenProvider returned anyhow::Result, and authenticated_llm_request reported every failure, including failing to mint an LLM token, as LanguageModelCompletionError::HttpSend. An expired session (401) or a missing subscription (402) during token minting therefore looked like a connectivity problem: the agent panel showed a stream error, and retry logic treated it as transient. Downstream consumers (Delta) had to dig typed errors back out of the anyhow chain to recover the real cause.

This PR:

  • Changes CloudLlmTokenProvider::cached_token/refresh_token to return Result<String, ClientApiError>, and Client::{cached,refresh,clear_and_refresh}_llm_token to match.
  • Adds LlmRequestError, returned by authenticated_llm_request, which separates token acquisition failures from building or sending the request.
  • Adds LlmRequestError::into_completion_error, which maps:
    • Unauthorized/NotSignedIn to a Zed Authentication rejection (not retried),
    • a token-endpoint 402 to the existing PaymentRequired rejection,
    • other token-endpoint statuses by HTTP status (for example 403 to Permission, 5xx to retryable InternalServer),
    • connection failures and send failures to HttpSend, as before.

In Zed, a token failure caused by an expired session now shows the agent panel's authentication error instead of a stream error. Messages stay neutral about whose credentials were rejected so callers can choose wording from the category.

Release Notes:

  • Improved the agent panel error shown when a Zed sign-in has expired.

…ions

`CloudLlmTokenProvider` returned `anyhow::Result`, and
`authenticated_llm_request` reported every failure, including failing to
mint an LLM token, as `LanguageModelCompletionError::HttpSend`. An
expired session (401) or a missing subscription (402) while minting a
token therefore looked like a connectivity problem: the agent showed a
stream error and retry logic treated it as transient.

Token providers now return `ClientApiError`, and
`authenticated_llm_request` returns an `LlmRequestError` that keeps token
acquisition separate from building or sending the request.
`LlmRequestError::into_completion_error` maps a rejected or missing
session to an `Authentication` rejection, a 402 to the existing
`PaymentRequired` rejection, other token-endpoint statuses by their HTTP
status, and connection failures to `HttpSend`. Callers that need
different wording for different credentials can match on the category.
@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Sep 25, 2026
@zed-community-bot zed-community-bot Bot added the staff Pull requests authored by a current member of Zed staff label Sep 25, 2026
@ConradIrwin
ConradIrwin added this pull request to the merge queue Sep 28, 2026
Merged via the queue into main with commit dd510f9 Sep 28, 2026
51 checks passed
@ConradIrwin
ConradIrwin deleted the typed-llm-token-errors branch September 28, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement staff Pull requests authored by a current member of Zed staff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants