{"record":{"id":"c78dcf842d977ed0","repo":"jackwener/OpenCLI","slug":"unexpected-evaluate-envelope-json-stringify-r","errorCode":null,"errorMessage":"unexpected evaluate envelope: ${JSON.stringify(r)}","messagePattern":"unexpected evaluate envelope: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/slock/errors.js","lineNumber":28,"sourceCode":"//   { 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":10,"sourceCodeEnd":31,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/slock/errors.js#L10-L31","documentation":"dispatchEvaluateResult's default branch throws CommandExecutionError with `unexpected evaluate envelope: <JSON>`. A null or unrecognized envelope indicates contract drift between the injected browser snippet and the CLI dispatcher — the snippet returned something outside the documented {kind: ...} protocol (following the 'fail loud' reddit precedent).","triggerScenarios":"page.evaluate returned null/undefined (snippet crashed or was blocked, e.g. CSP, navigation interrupted), or a modified/older snippet returned a shape without a recognized kind field.","commonSituations":"Browser page navigated mid-evaluate so the result is null; antivirus/extension stripping the injected script; half-updated CLI where snippet and dispatcher versions disagree.","solutions":["Rerun the command — transient navigation/CSP interruptions often resolve on retry","Upgrade the CLI so snippet and dispatcher versions match","Inspect the JSON in the message: if it's null, check the browser session/URL loads correctly; if it has an unexpected kind, report the contract drift"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const envelope = result && typeof result === 'object' && typeof result.kind === 'string' ? result : null;\nif (!envelope) throw new Error('evaluate returned no envelope — page may have navigated or script was blocked');","typeGuard":"const isEnvelope = (r) => r != null && typeof r === 'object' && ['ok','auth','http','no-server','unresolvable','no-thread'].includes(r.kind);","tryCatchPattern":"try { return dispatchEvaluateResult(result); } catch (e) { if (/unexpected evaluate envelope/.test(e.message)) { await page.reload(); return retryWithBackoff(task, 2); } throw e; }","preventionTips":["Avoid navigating or reloading the page while commands run","Keep snippet and dispatcher versions in sync (upgrade the whole CLI)","Check for browser extensions/CSP that strip injected scripts"],"tags":["contract-drift","cli","internal-bug"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}