{"record":{"id":"10b7327bca357b5c","repo":"can1357/oh-my-pi","slug":"cannot-export-in-memory-session-to-html","errorCode":null,"errorMessage":"Cannot export in-memory session to HTML","messagePattern":"Cannot export in-memory session to HTML","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/export/html/index.ts","lineNumber":276,"sourceCode":"\tconst sessionDataBase64 = Buffer.from(JSON.stringify(sessionData)).toBase64();\n\n\t// Use function replacements so `$'`, `$&`, `$$`, `$n`, etc. in the\n\t// substituted CSS/base64 are not interpreted as substitution patterns.\n\treturn getTemplate()\n\t\t.replace(\"<theme-vars/>\", () => `<style>${themeStyles}</style>`)\n\t\t.replace(\"{{SESSION_DATA}}\", () => sessionDataBase64);\n}\n\n/** Export session to HTML using SessionManager and AgentState. */\nexport async function exportSessionToHtml(\n\tsm: SessionManager,\n\tstate?: AgentState,\n\toptions?: ExportOptions | string,\n): Promise<string> {\n\tconst opts: ExportOptions = typeof options === \"string\" ? { outputPath: options } : options || {};\n\n\tconst sessionFile = sm.getSessionFile();\n\tif (!sessionFile) throw new Error(\"Cannot export in-memory session to HTML\");\n\n\tconst sessionData = buildSessionData(sm, state);\n\tif (opts.includeSubSessions !== false) {\n\t\tconst subSessions = await collectSubSessions(sessionFile);\n\t\tif (Object.keys(subSessions).length > 0) sessionData.subSessions = subSessions;\n\t}\n\n\tconst palette = opts.palette ?? (opts.themeName ? \"theme\" : \"web\");\n\tconst html = await generateHtml(sessionData, palette, opts.themeNames, opts.themeName);\n\tconst outputPath = opts.outputPath || `${APP_NAME}-session-${path.basename(sessionFile, \".jsonl\")}.html`;\n\n\tawait Bun.write(outputPath, html);\n\treturn outputPath;\n}\n\n/** Export session file to HTML (standalone). */\nexport async function exportFromFile(inputPath: string, options?: ExportOptions | string): Promise<string> {\n\tconst opts: ExportOptions = typeof options === \"string\" ? { outputPath: options } : options || {};","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/export/html/index.ts#L258-L294","documentation":"exportSessionToHtml renders a session to HTML from a SessionManager. Export requires a persisted session file to read (and to collect sub-sessions from); when the SessionManager was created purely in memory (no backing session file), getSessionFile() returns null and this error is thrown. It guards against exporting data that was never written to disk.","triggerScenarios":"Calling exportSessionToHtml(sm, ...) (directly or via exportToHtml) on a SessionManager opened without a file / created programmatically, so sm.getSessionFile() returns undefined.","commonSituations":"SDK embedding that constructs a SessionManager in memory for a scripted agent run and then tries to export the transcript; tests creating ephemeral sessions; calling export before the session was ever persisted.","solutions":["Persist the session first — ensure SessionManager was opened with a real session file path.","For in-memory sessions, serialize entries yourself and render via a lower-level HTML builder, or write a session file then export.","Check sm.getSessionFile() before calling and branch to an alternate export path when null."],"exampleFix":"// before\nawait exportToHtml(sessionManager); // in-memory session\n// after\nif (!sessionManager.getSessionFile()) {\n  throw new Error(\"Persist the session before exporting\");\n}\nawait exportToHtml(sessionManager);","handlingStrategy":"validation","validationCode":"if (!sm.getSessionFile()) {\n  throw new Error(\"Session has no backing file; persist it before exporting to HTML\");\n}\nawait exportToHtml(sm);","typeGuard":"function isExportable(sm: SessionManager): boolean {\n  return typeof sm.getSessionFile() === \"string\";\n}","tryCatchPattern":"try {\n  return await exportToHtml(sm);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"in-memory session\")) {\n    throw new Error(\"Open the session from a file (SessionManager.open) before exporting\");\n  }\n  throw err;\n}","preventionTips":["Only export sessions opened via SessionManager.open with a real path.","Check getSessionFile() before export in SDK/embedding code.","For scripted runs, persist the session file first, then export."],"tags":["export","session","state"],"backgroundTag":"unpersisted-session-export","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}