{"record":{"id":"c3aeed8689eb3da1","repo":"jackwener/OpenCLI","slug":"r-detail","errorCode":null,"errorMessage":"${r.detail}","messagePattern":"\\$\\{r\\.detail\\}","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/slock/auth-verify.js","lineNumber":10,"sourceCode":"import { AuthRequiredError, CommandExecutionError } from '@jackwener/opencli/errors';\nimport { buildFetchSnippet } from './in-page.js';\nimport { SLOCK_DOMAIN, SLOCK_HOME_URL } from './shared.js';\n\n// site-auth's whoami sets navigateBefore:false, so verify owns navigation.\nexport async function verifySlockSession(page) {\n  await page.goto(SLOCK_HOME_URL);\n  const snippet = buildFetchSnippet({ method: 'GET', path: '/auth/me', serverScoped: false });\n  const r = await page.evaluate(`(async () => { ${snippet} })()`);\n  if (r && r.kind === 'auth') throw new AuthRequiredError(SLOCK_DOMAIN, r.detail);\n  // unknown / null envelope = contract drift; same typed class as dispatchEvaluateResult\n  if (!r || r.kind !== 'ok') throw new CommandExecutionError(`unexpected /auth/me result: ${JSON.stringify(r)}`);\n  const me = r.rows ?? {};\n  return {\n    id: me.id ?? null,\n    name: me.name ?? me.displayName ?? me.username ?? null,\n    email: me.email ?? null,\n  };\n}\n","sourceCodeStart":1,"sourceCodeEnd":20,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/slock/auth-verify.js#L1-L20","documentation":"This AuthRequiredError re-wraps the server's auth-envelope detail. verifySlockSession performs GET /auth/me in the page; when the fetch snippet returns an envelope with kind === 'auth', the session is not authenticated on the Slock domain and the error surfaces the server-provided detail (e.g. invalid or expired session cookie).","triggerScenarios":"Running any command that verifies the session when the browser context has no valid Slock session cookie: never logged in, session expired, cookies cleared, or the server rejected the session.","commonSituations":"First run before `login`, stale browser profile after server-side session revocation, cookie jar wiped by automation, or SSO token expiry overnight.","solutions":["Re-run the login command for the Slock server to establish a fresh session.","Confirm the browser profile used by the CLI still holds Slock cookies (don't run headless with a fresh context).","Check the server's detail message for the exact reason (expired vs invalid) and act accordingly.","If sessions expire quickly, wrap commands with a re-login-on-AuthRequiredError flow."],"exampleFix":"// before\nconst me = await verifySlockSession(page);\n// after\nlet me;\ntry { me = await verifySlockSession(page); }\ncatch (e) {\n  if (e instanceof AuthRequiredError) { await login(page); me = await verifySlockSession(page); }\n  else throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const me = await verifySlockSession(page);\n} catch (e) {\n  if (e instanceof AuthRequiredError) {\n    await login(page);            // establish fresh session\n    return verifySlockSession(page);\n  }\n  throw e;\n}","preventionTips":["Always login before commands that hit the API.","Use a persistent browser profile so cookies survive runs.","Wrap long-running automations with re-login-on-AuthRequiredError logic.","Check session lifetime expectations for your Slock server."],"tags":["authentication","session-expired","cookies","auth-required"],"backgroundTag":"session-expired-reauth-required","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}