Stirling-Tools/Stirling-PDF · error · Error
Failed to save authentication token
Error message
Failed to save authentication token
What it means
Thrown by AuthService.login after the Rust 'login' invoke command already returned a valid token+refresh_token, but saveTokenEverywhere() failed to persist the token into the Tauri secure store / localStorage. The login was successful server-side; only local persistence failed. The underlying storage-layer error is preserved as error.cause, and auth status is NOT changed by this throw (the outer catch will reset it to unauthenticated).
Source
Thrown at frontend/editor/src/desktop/services/authService.ts:365
supabaseKey: SUPABASE_KEY,
saasServerUrl: STIRLING_SAAS_URL,
});
const {
token,
username: returnedUsername,
email,
refresh_token: refreshToken,
} = response;
// Save token to all storage locations. Supabase (SaaS) logins include a
// refresh token so the short-lived access token can be renewed; self-hosted
// logins return null here and refresh via the current access token instead.
try {
await this.saveTokenEverywhere(token, refreshToken);
} catch (error) {
console.error("[Desktop AuthService] Failed to save token:", error);
throw new Error("Failed to save authentication token", {
cause: error,
});
}
// Save user info to store
await invoke("save_user_info", {
username: returnedUsername || username,
email,
});
const userInfo: UserInfo = {
username: returnedUsername || username,
email: email || undefined,
};
this.setAuthStatus("authenticated", userInfo);
return userInfo;View on GitHub (pinned to 9ef20dcab8)
Solutions
- Inspect error.cause for the real storage-layer message (Tauri store write vs keyring access) and fix that specific layer.
- On Linux, ensure a secret-service implementation (gnome-keyring / kwallet) is running and unlocked before launching the app.
- Clear a corrupted store: remove the Tauri store file and localStorage key 'stirling_jwt', then retry login.
- If the keyring is permanently unavailable, reinstall the desktop app so the Tauri store/keyring plugins re-register.
- Free disk space on the volume holding the OS temp / app-data directory.
Example fix
// before: caller sees only the generic message
try { await authService.login(...); }
catch (e) { showError(e.message); }
// after: surface the real storage cause and offer retry
try { await authService.login(...); }
catch (e) {
if (e instanceof Error && e.message === 'Failed to save authentication token') {
showError(`Could not store your login: ${e.cause instanceof Error ? e.cause.message : e.cause}`);
offerRetry();
return;
}
throw e;
} Defensive patterns
Strategy: try-catch
Type guard
function isTokenSaveFailure(e: unknown): e is Error & { cause: unknown } {
return e instanceof Error && e.message === 'Failed to save authentication token';
} Try / catch
try { await authService.login(server, user, pass); }
catch (e) {
if (isTokenSaveFailure(e)) {
// login worked server-side; only local persistence failed -> safe to retry login
const cause = e instanceof Error ? (e as any).cause : undefined;
reportStorageError(cause);
return;
}
throw e;
} Prevention
- Verify the OS keyring/credential store is available before showing the login form on desktop.
- Clear corrupted Tauri store / localStorage on startup if a version migration is detected.
- Never swallow error.cause — it is the only indicator of which storage layer failed.
When it happens
Trigger: saveTokenEverywhere(token, refreshToken) rejects. Concretely: the Tauri store plugin command fails to write, the OS keyring/credential store is locked or missing, the store JSON is corrupted, the disk is full, or a keychain permission prompt was declined.
Common situations: Running on a headless/CI Linux box with no secret-service daemon; a corporate machine where the login keychain is locked at the moment of login; a corrupted stirling_jwt / Tauri store file left from an older app version; disk-full on the volume holding the Tauri app data dir.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unable to open system browser for SSO. Please check your sys
- No authentication token available
- IndexedDB context not available
- Database not initialized
- No history chain found for file.
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/dfada1905d3dce1e.
Report an issue: GitHub.