Wei-Shaw/sub2api · error
auth.linuxdo.callbackMissingToken
Error message
auth.linuxdo.callbackMissingToken
What it means
In frontend/src/views/auth/LinuxDoCallbackView.vue:583, finalizeCompletion() handles the LinuxDo OAuth exchange completion. After the bind branch, it requires isOAuthLoginCompletion(completion) — a response with access_token. Any other shape throws the localized 'auth.linuxdo.callbackMissingToken'. This mirrors the DingTalk callback: the backend exchange returned a completion that is neither bind nor login.
Source
Thrown at frontend/src/views/auth/LinuxDoCallbackView.vue:583
states.includes('bind_login_required') ||
states.includes('bind_login') ||
states.includes('adopt_existing_user_by_email') ||
states.includes('existing_account_required') ||
states.includes('existing_account_binding_required')
}
async function finalizeCompletion(completion: PendingOAuthExchangeResponse, redirect: string) {
if (getOAuthCompletionKind(completion) === 'bind') {
const bindRedirect = sanitizeRedirectPath(completion.redirect || '/profile')
clearPendingAuthSession()
clearAllAffiliateReferralCodes()
appStore.showSuccess(bindSuccessMessage)
await router.replace(bindRedirect)
return
}
if (!isOAuthLoginCompletion(completion)) {
throw new Error(t('auth.linuxdo.callbackMissingToken'))
}
persistOAuthTokenContext(completion)
await authStore.setToken(completion.access_token)
clearAllAffiliateReferralCodes()
appStore.showSuccess(t('auth.loginSuccess'))
await router.replace(redirect)
}
async function finalizePendingAccountResponse(completion: LinuxDoPendingActionResponse) {
applyAdoptionSuggestionState(completion)
const redirect = sanitizeRedirectPath(completion.redirect || redirectTo.value)
if (completion.error === 'invitation_required') {
pendingAccountAction.value = 'none'
needsInvitation.value = true
needsAdoptionConfirmation.value = false
isProcessing.value = falseView on GitHub (pinned to 073e92d171)
Solutions
- Inspect the exchange response payload in the network tab to see exactly what the backend returned.
- Verify the OAuth session cookie survives the redirect (SameSite settings, cross-site context).
- Route any non-bind/non-login completion to a friendly restart-login flow instead of throwing raw.
- Align frontend/backend versions to eliminate schema drift.
Example fix
// before
if (!isOAuthLoginCompletion(completion)) {
throw new Error(t('auth.linuxdo.callbackMissingToken'))
}
// after
if (!isOAuthLoginCompletion(completion)) {
appStore.showError(t('auth.linuxdo.callbackMissingToken'))
await router.replace('/login')
return
} Defensive patterns
Strategy: type-guard
Type guard
function isLoginCompletion(c: PendingOAuthExchangeResponse): c is PendingOAuthExchangeResponse & { access_token: string } {
return getOAuthCompletionKind(c) !== 'bind' && typeof (c as any).access_token === 'string' && (c as any).access_token.length > 0;
} Try / catch
try { await finalizeCompletion(completion, redirect); }
catch (e) {
if (e.message === t('auth.linuxdo.callbackMissingToken')) {
showError('Login session expired — please retry');
await router.replace('/login'); return;
}
throw e;
} Prevention
- Ensure the OAuth session cookie survives the provider redirect (SameSite/domain config)
- Add a pending/error branch to finalizeCompletion instead of throwing on unknown shapes
- Keep frontend and backend versions aligned
When it happens
Trigger: LinuxDo OAuth code exchange returns 2xx without access_token: state/session cookie lost between redirect and callback so the server returns an incomplete completion; response field renamed by a backend update; double-callback (user refreshes) consuming the one-time exchange.
Common situations: Strict cookie settings (ITP/Safari) dropping the OAuth session cookie across the redirect; frontend/backend version skew; callback URL opened twice; LinuxDo provider outage returning an error the backend wrapped as an empty completion.
Related errors
- auth.dingtalk.callbackMissingToken
- auth.oidc.callbackMissingToken
- auth.oidc.callbackMissingToken
- auth.verifyFailed
- Passkeys are not supported by this browser
AI-assisted analysis of Wei-Shaw/sub2api@073e92d171 (2026-08-15).
Data as JSON: /api/errors/425034b58fafbccc.
Report an issue: GitHub.