Hive Hive
Sign in

Transient 503 on /api/auth/refresh_token hard-fails tuist generate instead of falling back to local cache

GitHub issue · Open

Metadata
Source
tuist/tuist #12089
Updated
Jul 26, 2026
Domains
CLI Cache
Details

What happened

During a roughly one-minute window (2026-07-26 06:10:05Z06:11:09Z) two Tuist server endpoints returned HTTP 503:

POST /api/auth/refresh_token → 503
GET /api/analytics?project_id=<org>%2F<project> → 503

The response body was an nginx error page rather than Tuist’s usual JSON error shape, served through Cloudflare — so this looked like an origin/upstream blip rather than an application-level error:

<html><head><title>503 Service Temporarily Unavailable</title></head>
<center><h1>503 Service Temporarily Unavailable</h1></center>

Tuist retried each call three times (Received HTTP 503 for POST /api/auth/refresh_token, retrying (1/3)...) and then aborted the command with:

✖ Error
Failed to retrieve cache endpoints due to an unknown server response of 503.

The outage recovered on its own. POST /api/auth/refresh_token now returns 400 to an empty body (i.e. alive and validating), and a later session in the same project logged zero 503s. I’m not filing this about the downtime — I’m filing it about how the client handled it.

Issue 1 — a transient auth/analytics 503 hard-fails tuist generate

Neither failing endpoint is required to generate a project. Remote cache is an accelerator, and /api/analytics is fire-and-forget telemetry. But the 503 on token refresh aborted tuist generate outright, so the command could not produce a project at all.

I’d expect a degrade-with-warning here: fall back to local cache, skip analytics, carry on. That fallback demonstrably works — the identical command succeeds with the remote token removed from the environment:

$ env -u TUIST_TOKEN -u TUIST_CONFIG_TOKEN tuist generate --no-open
✔ Success
Project generated.

So the capability to proceed without the server is already there; it just isn’t reached when the auth refresh fails.

Issue 2 — the error message points at the wrong subsystem

The message names “cache endpoints”, but the failing requests are auth-token refresh and analytics. That cost real debugging time: I went looking at cache.tuist.dev (which doesn’t resolve — presumably by design) before finding the actual 503s in ~/.local/state/tuist/sessions/<id>/logs.txt. Surfacing the failing path and status in the user-facing error, or saying “could not authenticate with the Tuist server”, would have pointed straight at it.

Impact

This ran inside an automated App Store screenshot pipeline that calls tuist generate before rendering. It failed five consecutive times over about an hour, with the misleading cache message each time. Setting env -u TUIST_TOKEN unblocked it permanently.

Environment

Tuist 4.202.5
macOS 26.5.1 (25F80)
Xcode 26.6

Org/project redacted; happy to share the x-request-id values and full session logs privately if that helps you correlate the incident.

Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments
D
dosubot[bot] Jul 26, 2026

Hi @leojkwan! I’m Dosu and I’m helping the Tuist team.

Great write-up — I dug into the codebase and can confirm both issues you’ve identified.

Issue 1 — No graceful degradation on transient server errors: The CLI currently distinguishes between “no token present” (proceeds in local-only mode) and “token present but server unavailable” (aborts). When POST /api/auth/refresh_token returns a 503, the RetryMiddleware retries it 3 times with exponential backoff [1]. After exhausting retries, the 503 is mapped to RefreshAuthTokenServiceError.unknownError(statusCode) [2], which is then converted to ClientAuthenticationError.notAuthenticated and thrown — aborting the command entirely [3]. The only network error that gets special handling is notConnectedToInternet; all other failures (including 503s) become hard auth errors [4]. So the local-only fallback path exists but is unreachable when a token is configured and the server is temporarily down.

Issue 2 — Misleading error message: The message “Failed to retrieve cache endpoints due to an unknown server response of 503” actually does come from GetCacheEndpointsService [5], which is a separate call that also hits the server and also fails with 503. So the message is technically accurate for that request, but it’s confusing because the root cause is the upstream outage affecting auth and all other server calls — not a cache-specific problem. Surfacing the failing path and status (as you suggest) would make this much clearer.

There’s a related infrastructure-side discussion in #11955 about Kura region 503s during bootstrap, though that’s focused on the server side rather than CLI-side fallback behavior [6].

Your suggestion to degrade-with-warning (fall back to local cache, skip analytics, continue generating) when the server returns transient errors seems like a solid improvement — the capability is already there, it’s just gated on “no token” rather than “server unreachable.”

To reply, just mention @dosu.


Docs are dead. Just use Dosu.

Leave Feedback Ask Dosu about tuist Share Dosu with your team