QuantumNous/new-api · warning · Error
Failed to sign out session
Error message
Failed to sign out session
What it means
Thrown by resetSession() in use-oauth-login.ts when the logout API responds with success falsy. The hook treats a failed logout as fatal before clearing local authentication state, so the user stays signed in locally even though they asked to sign out. The thrown message prefers the server's message and falls back to the translated generic string.
Source
Thrown at web/src/features/auth/hooks/use-oauth-login.ts:65
const [isTelegramPending, setIsTelegramPending] = useState(false)
const [githubButtonText, setGithubButtonText] = useState('')
const [githubButtonDisabled, setGithubButtonDisabled] = useState(false)
const githubTimeoutRef = useRef<NodeJS.Timeout | null>(null)
useEffect(() => {
setGithubButtonText(t('Continue with GitHub'))
return () => {
if (githubTimeoutRef.current) {
clearTimeout(githubTimeoutRef.current)
}
}
}, [t])
const resetSession = async () => {
const response = await logout()
if (!response.success) {
throw new Error(response.message || t('Failed to sign out session'))
}
clearAuthentication()
}
const handleGitHubLogin = async () => {
if (!status?.github_client_id) return
if (githubButtonDisabled) return
setIsLoading(true)
setGithubButtonDisabled(true)
setGithubButtonText(t('Redirecting to GitHub...'))
if (githubTimeoutRef.current) {
clearTimeout(githubTimeoutRef.current)
}
githubTimeoutRef.current = setTimeout(() => {
setIsLoading(false)View on GitHub (pinned to e2c7aa7b10)
Solutions
- Check the logout request's response in DevTools — an expired/invalid session usually still succeeds; a 4xx/5xx indicates the real problem.
- Decide whether local sign-out should proceed even when the server call fails: clearAuthentication() is currently skipped, keeping stale local state.
- Retry the logout after re-authenticating or when the backend is reachable.
- If the backend returns success:false for already-invalid sessions, treat that case as success client-side.
Example fix
// before
const resetSession = async () => {
const response = await logout()
if (!response.success) {
throw new Error(response.message || t('Failed to sign out session'))
}
clearAuthentication()
}
// after — always clear local state; surface server failure as a toast, not a blocker
const resetSession = async () => {
try {
const response = await logout()
if (!response.success) {
toast.error(response.message || t('Failed to sign out session'))
}
} finally {
clearAuthentication()
}
} Defensive patterns
Strategy: fallback
Try / catch
try {
await resetSession()
} catch {
// still clear local state so the user is effectively signed out client-side
clearAuthentication()
} Prevention
- Always clearAuthentication() in a finally block so local sign-out never dead-ends
- Treat 'session already invalid' logout failures as success
- Show server logout failures as warnings, not blockers, during account-switch flows
When it happens
Trigger: Calling resetSession() while the session token is already expired or revoked (backend rejects POST /api/user/logout); backend temporarily unavailable behind the same origin; logout endpoint returning success:false for an invalid session.
Common situations: User clicks 'switch account' on the OAuth screen after their token expired in another tab; backend restarted losing in-memory session store; reverse proxy returning 502 bodies parsed as {success:false}.
Related errors
- Failed to initialize OAuth
- Unsupported verification method: {{method}}
- Failed to start verification
- Passkey verification was cancelled
- Verification scope is missing
AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15).
Data as JSON: /api/errors/0cc33e6f2532d384.
Report an issue: GitHub.