{"record":{"id":"21cfec7cc839e21c","repo":"mastra-ai/mastra","slug":"session-workspace-is-not-available","errorCode":null,"errorMessage":"Session workspace is not available","messagePattern":"Session workspace is not available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/routes/fs.ts","lineNumber":556,"sourceCode":"      updatedAt: new Date((Number(mtimeStr) || 0) * 1000).toISOString(),\n    });\n  }\n  entries.sort((a, b) => a.path.localeCompare(b.path));\n\n  return { workspacePath: session.sessionId, root: safeRoot, rootPath, entries };\n}\n\n/** Read a file inside a session's sandbox. Paths outside rendered roots require a persisted-file allowlist check in the route. */\nexport async function readSessionWorkspaceFile(\n  session: SourceControlSession,\n  path: string,\n  options: { allowUnapprovedPath?: boolean } = {},\n): Promise<WorkspaceFile> {\n  const safePath = assertRelativePath(path, 'path');\n  if (!options.allowUnapprovedPath) assertApprovedRenderedRoot(safePath.split('/')[0] ?? '');\n\n  const handle = await sessionSandbox(session);\n  if (!handle) throw new Error('Session workspace is not available');\n  const { filesystem } = handle;\n  const info = await filesystem.stat(safePath);\n  if (info.type === 'directory') throw new Error('Path is a directory');\n\n  const buffer = (await filesystem.readFile(safePath)) as Buffer;\n  const truncated = buffer.length > MAX_TEXT_FILE_BYTES;\n  const base = {\n    workspacePath: session.sessionId,\n    path: safePath,\n    name: posixPath.basename(safePath),\n    size: buffer.length,\n    updatedAt: info.modifiedAt.toISOString(),\n  };\n  try {\n    const content = TEXT_DECODER.decode(truncated ? buffer.subarray(0, MAX_TEXT_FILE_BYTES) : buffer);\n    return { ...base, contentType: 'text', content, truncated };\n  } catch {\n    return { ...base, contentType: 'unsupported' };","sourceCodeStart":538,"sourceCodeEnd":574,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/routes/fs.ts#L538-L574","documentation":"readSessionWorkspaceFile resolves the session's sandbox (workspace handle) via sessionSandbox(session); if no sandbox exists for the session there is no filesystem to stat/read, so the function throws. This means the session has no live workspace handle at read time.","triggerScenarios":"Calling readSessionWorkspaceFile (or the file route in buildFsRoutes) for a session whose sandbox has not been created yet or has been torn down (session ended, sandbox reclaimed, or workspace provisioning failed).","commonSituations":"Reading a file from a stale session after the agent run finished and the sandbox was recycled; querying a session before the workspace was provisioned; environment where sandbox startup failed so handles are never registered.","solutions":["Ensure the session's sandbox/workspace is started and attached before attempting file reads.","Check sessionSandbox(session) for the target session; if null, reinitialize or recreate the session workspace.","If the session is finished, re-open or resume the session so its workspace handle is restored before reading files.","Handle the null-handle case in the route and return a clear 404/409 so clients can refetch a fresh session."],"exampleFix":"// before\nconst file = await readSessionWorkspaceFile(session, 'src/index.ts');\n// after\nconst handle = await sessionSandbox(session);\nif (!handle) await resumeSessionWorkspace(session); // provision workspace first\nconst file = await readSessionWorkspaceFile(session, 'src/index.ts');","handlingStrategy":"try-catch","validationCode":"const handle = await sessionSandbox(session);\nconst canRead = Boolean(handle);\nif (!canRead) await provisionOrResumeWorkspace(session);","typeGuard":"async function workspaceAvailable(session: SourceControlSession): Promise<boolean> {\n  return (await sessionSandbox(session)) != null;\n}","tryCatchPattern":"try {\n  const file = await readSessionWorkspaceFile(session, path);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Session workspace is not available') {\n    await resumeSessionWorkspace(session); // recreate the sandbox, then retry once\n    const file = await readSessionWorkspaceFile(session, path);\n  } else throw e;\n}","preventionTips":["Keep sessions alive (or explicitly resume them) for as long as clients may read workspace files.","Treat sandbox teardown as terminal: stop serving file APIs for ended sessions.","Monitor workspace provisioning failures so sessions never exist without a sandbox."],"tags":["workspace","session","lifecycle"],"backgroundTag":"workspace-unavailable","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}