{"record":{"id":"789fff512e5e9390","repo":"jackwener/OpenCLI","slug":"r-detail-789fff","errorCode":null,"errorMessage":"${r.detail}","messagePattern":"\\$\\{r\\.detail\\}","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/slock/errors.js","lineNumber":16,"sourceCode":"import { ArgumentError, AuthRequiredError, CommandExecutionError, ConfigError } from '@jackwener/opencli/errors';\nimport { SLOCK_DOMAIN } from './shared.js';\n\n// EvaluateResult is the envelope every in-page snippet returns. Kinds:\n//   { kind: 'ok', rows, meta? }\n//   { kind: 'auth', detail }\n//   { kind: 'http', status, where }\n//   { kind: 'no-server', detail }\n//   { kind: 'unresolvable', detail }\n//   { kind: 'no-thread', parent }       // handled by caller, never reaches dispatcher\nexport function dispatchEvaluateResult(r) {\n  switch (r && r.kind) {\n    case 'ok':\n      return r.rows;\n    case 'auth':\n      throw new AuthRequiredError(SLOCK_DOMAIN, r.detail);\n    case 'http':\n      throw new CommandExecutionError(`HTTP ${r.status} from ${r.where}`);\n    case 'no-server':\n      throw new ConfigError(r.detail, 'Run `opencli slock server-use <slug>` to set the active server.');\n    case 'unresolvable':\n      throw new ArgumentError(r.detail);\n    case 'no-thread':\n      // caller decides what to do (returns a 0-row hint); should never reach here\n      throw new CommandExecutionError(`no-thread should be handled by caller, not dispatcher: ${r.parent}`);\n    default:\n      // unknown / null envelope = contract drift; fail loud (reddit precedent)\n      throw new CommandExecutionError(`unexpected evaluate envelope: ${JSON.stringify(r)}`);\n  }\n}\n","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/slock/errors.js#L1-L31","documentation":"dispatchEvaluateResult maps an 'auth' envelope from the in-page snippet to AuthRequiredError, carrying the API's detail message (rendered as ${r.detail}). It means the slock web session is not authenticated — the fetch inside the page got an auth rejection and the snippet bubbled that up.","triggerScenarios":"Running any slock read command (rows, channel actions, data, c, list, thread-state) without being logged in to the SLOCK_DOMAIN in the automated browser; session cookie expired or was cleared.","commonSituations":"Fresh browser profile with no login; session invalidated server-side (password change, logout elsewhere); cookie expiry after long idle.","solutions":["Log in to the slock web app in the automated browser session, then rerun the command","Run the slock auth/login command if the CLI provides one to establish a session","Re-check you are pointing at the right server (`opencli slock server-use <slug>`) since auth is per-server scoped"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// verify a session exists before running commands:\n// open in the automated browser and confirm you are logged in to SLOCK_DOMAIN\ncp.execSync('opencli slock server-use my-workspace');","typeGuard":"const isAuthError = (e) => e && e.name === 'AuthRequiredError';","tryCatchPattern":"try { await slockCommand(); } catch (e) { if (isAuthError(e)) { console.error('Not authenticated — log in to the slock web app, then retry'); process.exit(3); } throw e; }","preventionTips":["Log in to the slock web app in the automation browser profile before batch runs","Re-authenticate after long idle periods or password changes","Include a pre-flight auth check in CI scripts"],"tags":["auth","session-expired","cli"],"backgroundTag":"auth-session-required","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}