{"record":{"id":"6d1c7843db41b5b5","repo":"windmill-labs/windmill","slug":"not-logged-in","errorCode":null,"errorMessage":"Not logged in","messagePattern":"Not logged in","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"frontend/src/routes/(root)/+layout.svelte","lineNumber":143,"sourceCode":"\t\t\tawait refreshSuperadmin()\n\n\t\t\tif ($workspaceStore) {\n\t\t\t\tif (await tryRecoverFromDeletedWorkspace($workspaceStore)) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif ($userStore) {\n\t\t\t\t\tconsole.log(`Welcome back ${$userStore.username} to ${$workspaceStore}`)\n\t\t\t\t} else {\n\t\t\t\t\tconst ws = $workspaceStore\n\t\t\t\t\tconst user = await getUserExt(ws)\n\t\t\t\t\t// A switch mid-flight means this answers for the workspace we left, and\n\t\t\t\t\t// that switch has already started the fetch answering for the active\n\t\t\t\t\t// one: neither this role nor its failure describes where we are now.\n\t\t\t\t\tif ($workspaceStore !== ws) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\tthrow Error('Not logged in')\n\t\t\t\t\t}\n\t\t\t\t\t$userStore = user\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (\n\t\t\t\t\t(!page.url.pathname.startsWith('/user/') || page.url.pathname.startsWith('/user/cli')) &&\n\t\t\t\t\t!page.url.pathname.startsWith('/oauth/mcp_authorize') &&\n\t\t\t\t\t// The hub import wizard asks for the destination itself, and may end in a\n\t\t\t\t\t// workspace that does not exist yet — bouncing it to the picker would\n\t\t\t\t\t// force the very choice it exists to make.\n\t\t\t\t\t!page.url.pathname.startsWith(`${base}/projects/import`)\n\t\t\t\t) {\n\t\t\t\t\tgoto(\n\t\t\t\t\t\t`/user/workspaces?rd=${encodeURIComponent(page.url.href.replace(page.url.origin, ''))}`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tlet user = await UserService.globalWhoami()\n\t\t\t\tconsole.log(`Welcome back ${user.email}`)","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/routes/(root)/+layout.svelte#L125-L161","documentation":"In the root layout `loadUser`, after workspace resolution completes (and only if the active workspace has not switched away), a null user means there is no authenticated session, so the layout throws 'Not logged in' to redirect to login.","triggerScenarios":"Loading any protected route without a valid session cookie/token, after session expiry, after logout with a stale in-memory store, or when the /user/me-style fetch returns null for the current workspace context.","commonSituations":"Token expired after idle time, sharing a link directly without logging in, backend restarted without the session store, or the guard bailing because $workspaceStore changed mid-fetch leaving user null.","solutions":["Log in again — this is the expected unauthenticated-state signal","Check that your session cookie is present and not expired","If you believe you are logged in, verify the frontend REMOTE points at the backend you authenticated against","Clear stale state (logout fully) and re-authenticate"],"exampleFix":"// before: assume logged in\nawait goto('/');\n// after: guard\ntry { await loadUser(); } catch (e) {\n  if (String(e) === 'Error: Not logged in') await goto('/user/login');\n  else throw e;\n}","handlingStrategy":"try-catch","validationCode":"// before navigating to a protected route\nconst res = await fetch(`${backendUrl}/api/users/whoami`);\nif (res.status === 401 || res.status === 403) await goto('/user/login');","typeGuard":"function isLoggedIn(user: unknown): user is { email: string; is_admin?: boolean } {\n  return !!user && typeof (user as any).email === 'string';\n}","tryCatchPattern":"try { await loadUser(); } catch (e) {\n  if (/Not logged in/.test(String(e))) await goto('/user/login?redirect=' + encodeURIComponent(location.pathname));\n  else throw e;\n}","preventionTips":["Guard protected routes with an auth check before deep links are shared","Re-authenticate after long idle periods","Verify the frontend points at the backend instance you authenticated against","Clear stale workspace/user stores on logout"],"tags":["auth","session","routing"],"backgroundTag":"not-authenticated","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}