{"record":{"id":"7d08ab9f03bec130","repo":"mastra-ai/mastra","slug":"factory-session-session-sessionid-was-retired-d","errorCode":null,"errorMessage":"Factory session ${session.sessionId} was retired during workspace materialization","messagePattern":"Factory session (.+?) was retired during workspace materialization","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/workspace.ts","lineNumber":682,"sourceCode":"    // sandbox: construction is eager while the VM start is lazy, so a session\n    // retired before its first tool call still has a workspace (and possibly a\n    // token injector) that must be torn down.\n    const registered = await workspaceRegistry.register(\n      session.sessionId,\n      workspaceId,\n      workspaceGeneration,\n      async () => {\n        githubTokenInjectors.delete(workspaceId);\n        constructedWorkspaces.delete(workspaceId);\n        // Retirement drops the memoized session sandbox so a later re-open\n        // constructs (and the provider resolves) fresh instead of reusing an\n        // instance whose VM the retirement path may stop or destroy.\n        evictSessionSandbox(session.id);\n        await mastra?.removeWorkspace?.(workspaceId);\n      },\n    );\n    if (!registered) {\n      throw new Error(`Factory session ${session.sessionId} was retired during workspace materialization`);\n    }\n\n    // Fully lazy: nothing provisions until the first real sandbox operation\n    // (`ensureRunning()` inside the provider). A background warm-up at session\n    // start was considered and dropped — it speculatively created a VM for\n    // every session, including ones whose agent never touches the workspace.\n    return workspace;\n  };\n}\n","sourceCodeStart":664,"sourceCodeEnd":692,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/workspace.ts#L664-L692","documentation":"While a workspace is being materialized, the Factory session can concurrently be retired (user closed it, timeout, admin action). After registration completes, the code checks whether registration is still present; if the retirement path already removed it, creation aborts with this error because continuing would produce a workspace backed by a VM the retirement path may stop or destroy.","triggerScenarios":"`createWorkspaceFactory` calls the registration step which returns null (`registered` is falsy) because `evictSessionSandbox`/retirement ran between session setup and workspace registration for `session.sessionId`.","commonSituations":"User closes/retires the session while the first workspace is still materializing; idle-timeout retirement racing with a slow clone/setup; admin force-retires a stuck session; retry logic re-entering after retirement.","solutions":["Retry the agent request — it will fail cleanly against the retired session or a new session will be created","Confirm the session is actually retired and start a new Factory session","If it fires while the session is still alive, check for a retirement race: look at logs for evictSessionSandbox around this error","Slow setups increase the race window — speed up setupCommand or move heavy work out of materialization"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// check session liveness before materializing\nconst state = await getSessionState(session.id);\nif (state.status !== 'active') {\n  throw new Error(`Session ${session.sessionId} is ${state.status}; start a new session before materializing workspaces`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const factory = await createWorkspaceFactory(session);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('was retired during workspace materialization')) {\n    const fresh = await createSession(); // start a new session, then retry\n    return createWorkspaceFactory(fresh);\n  }\n  throw e;\n}","preventionTips":["Avoid retiring sessions while initial workspace setup is in flight (grace period)","Keep setupCommand fast so the materialization window is small","Detect retirement early (poll or webhook) and abort materialization proactively","Surface 'session closed' in the UI instead of retrying against a retired session"],"tags":["race-condition","session-lifecycle","workspace","factory"],"backgroundTag":"session-retired-during-operation","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}