fix: log WARN on transient Railway token-refresh failures and continue with stored token #SUPERLOG
Summary
When Railway's OAuth token endpoint returns a transient non-JSON response (invalid_response) or a server_error, the worker was logging ERROR and skipping the entire installation for that pass — even though the stored access token is still valid for up to 5 more minutes (refresh fires when expiresAt - now() < 5 min).
This is a third recurrence of the same defect (incidents yeasty-skunk, wandering-porcupine, and now quiet-walrus). Two previous fix PRs (#440, #471) prescribed the same change but were both closed without merging.
Root cause
In apps/worker/src/railway/puller.ts, the token-refresh failure path called deps.log.error(...) and return'd unconditionally, discarding the remaining valid-token window:
// Before
if (!refreshed.ok) {
stats.errors += 1;
deps.log.error({ installation_id, error: refreshed.error }, "railway token refresh failed");
return; // ← skips even when token still valid
}
accessToken = refreshed.accessToken;
await deps.store.saveTokens(...);
Remediation
- Log WARN (not ERROR) on a transient refresh failure — Railway's token endpoint sometimes returns non-JSON bodies under load.
- Only skip the installation if
expiresAt <= now()(token is truly expired); otherwise continue the pass with the stored access token. - Move
accessToken = refreshed.accessTokenandsaveTokens(...)into theelsebranch so they only run on success. - Two new tests cover both branches: (a) transient failure, token still valid → continues and logs WARN; (b) failure with expired token → skips.
All 8 tests pass: pnpm tsx --test apps/worker/src/railway/puller.test.ts
Fixes incident quiet-walrus (22394ecc-55dd-4554-af1b-d51d7689b80b).
Was this PR helpful? Leave feedback — goes straight to the Superlog team.
Summary by cubic
Fixes the Railway puller skipping installations when a token refresh fails transiently. Previously any refresh failure logged ERROR and aborted the pass, even though the stored access token is valid for up to 5 more minutes. The puller now logs WARN and continues with the stored token when it hasn't expired. This is the third occurrence of this defect, after two earlier fix PRs were closed without merging.
- Only skips the installation when
expiresAthas passed; token assignment andsaveTokensnow run only on successful refresh. - Adds tests for both the still-valid and truly-expired paths.