{"record":{"id":"64a310a8d61668f1","repo":"Hmbown/CodeWhale","slug":"mobile-session-bootstrap-was-incomplete","errorCode":null,"errorMessage":"Mobile session bootstrap was incomplete","messagePattern":"Mobile session bootstrap was incomplete","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_mobile.html","lineNumber":325,"sourceCode":"      state.streamTicket = \"\";\n      sessionStorage.removeItem(SESSION_STORAGE_KEY);\n    }\n\n    function loadMobileSession() {\n      try {\n        const stored = JSON.parse(sessionStorage.getItem(SESSION_STORAGE_KEY) || \"null\");\n        if (stored && typeof stored.requestProof === \"string\") {\n          state.requestProof = stored.requestProof;\n          state.streamTicket = typeof stored.streamTicket === \"string\" ? stored.streamTicket : \"\";\n        }\n      } catch (_) {\n        clearMobileSession();\n      }\n    }\n\n    function useMobileSession(session) {\n      if (!session || typeof session.request_proof !== \"string\") {\n        throw new Error(\"Mobile session bootstrap was incomplete\");\n      }\n      state.requestProof = session.request_proof;\n      state.streamTicket = typeof session.stream_ticket === \"string\" ? session.stream_ticket : \"\";\n      saveMobileSession();\n    }\n\n    function takeMobileSessionFromUrl() {\n      const hash = location.hash.startsWith(\"#\") ? location.hash.slice(1) : \"\";\n      const params = new URLSearchParams(hash);\n      const requestProof = params.get(\"request_proof\");\n      const streamTicket = params.get(\"stream_ticket\");\n      if (!requestProof || !streamTicket) return;\n      useMobileSession({ request_proof: requestProof, stream_ticket: streamTicket });\n      params.delete(\"request_proof\");\n      params.delete(\"stream_ticket\");\n      const nextHash = params.toString();\n      history.replaceState(\n        null,","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/runtime_mobile.html#L307-L343","documentation":"The mobile web runtime persists its session in localStorage and restores it via useMobileSession(session). If the restored/returned session object is missing or its `request_proof` field is not a string, the bootstrap data needed to authenticate subsequent API calls is absent, so the runtime refuses to adopt the session.","triggerScenarios":"Calling useMobileSession with null/undefined, or with an object whose `request_proof` is missing, null, or a non-string (e.g. a stale or hand-edited localStorage value, or a server response missing the field).","commonSituations":"A stale or schema-changed saved session in localStorage after a Runtime upgrade; a server that changed the session payload shape; manually clearing/corrupting localStorage entries.","solutions":["Clear the saved mobile session (clearMobileSession() or remove the localStorage key) and reconnect with a Runtime token via connectMobileSession.","Verify the endpoint that produces the session still returns a string `request_proof` field.","Check for version mismatch between the served runtime_mobile.html and the Runtime server API."],"exampleFix":"// before\nuseMobileSession(JSON.parse(localStorage.getItem('codewhale-mobile-session')));\n// after\nconst saved = JSON.parse(localStorage.getItem('codewhale-mobile-session') || 'null');\nif (saved && typeof saved.request_proof === 'string') useMobileSession(saved);\nelse await connectMobileSession();","handlingStrategy":"validation","validationCode":"if (!session || typeof session.request_proof !== 'string') {\n  clearMobileSession();\n  await connectMobileSession();\n} else {\n  useMobileSession(session);\n}","typeGuard":"function isUsableSession(s) {\n  return !!s && typeof s.request_proof === 'string';\n}","tryCatchPattern":"try {\n  useMobileSession(savedSession);\n} catch {\n  clearMobileSession();\n  await connectMobileSession();\n}","preventionTips":["Always clear and re-bootstrap the session when the stored shape does not validate.","Version the localStorage key so schema changes invalidate old sessions.","Never hand-edit stored session blobs."],"tags":["mobile","session","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T21:17:16.096Z"}