moeru-ai/airi · error · Error
Unable to reload missing extension session: ${sessionId}
Error message
Unable to reload missing extension session: ${sessionId} What it means
Thrown by ExtensionHost.reload() when no session exists for the given sessionId. Reload preserves the prior session's manifest, cwd, and runtime intent, so it requires a live session to read that state from; without one it cannot deterministically re-bootstrap.
Source
Thrown at packages/plugin-sdk/src/plugin-host/core.ts:847
return await this.dependencies.waitFor(key, timeoutMs)
}
async stop(sessionId: string): Promise<ExtensionSession | undefined> {
const extensionSession = this.extensionSessionService.get(sessionId)
if (!extensionSession) {
return undefined
}
await this.cleanupExtensionSession(extensionSession)
return extensionSession
}
async reload(sessionId: string, options: ExtensionStartOptions = {}): Promise<ExtensionSession> {
// Reload preserves manifest/runtime intent, then performs stop + fresh start.
// This intentionally creates a new session identity for deterministic re-bootstrap.
const previousExtension = this.extensionSessionService.get(sessionId)
if (!previousExtension) {
throw new Error(`Unable to reload missing extension session: ${sessionId}`)
}
const manifest = previousExtension.manifest
await this.cleanupExtensionSession(previousExtension)
return this.start(manifest, {
...options,
cwd: options.cwd ?? previousExtension.cwd,
runtime: options.runtime ?? previousExtension.runtime,
})
}
}
View on GitHub (pinned to 27111382b4)
Solutions
- Confirm the session is still live via host.getSession(sessionId) before calling reload().
- If the session was stopped, call host.start(manifest) with the original manifest instead of reload().
- Avoid calling reload() concurrently with stop(); serialize teardown and restart.
Example fix
// before
await host.stop(session.id)
await host.reload(session.id) // throws: session already removed
// after
const existing = host.getSession(session.id)
if (existing) {
await host.reload(session.id)
} else {
await host.start(manifest)
} Defensive patterns
Strategy: validation
Validate before calling
const session = host.getSession(sessionId)
if (!session) {
throw new Error(`Session '${sessionId}' is not active. Use host.start(manifest) instead of reload.`)
}
await host.reload(sessionId) Type guard
function canReload(host: ExtensionHost, sessionId: string): boolean {
return host.getSession(sessionId) !== undefined
} Try / catch
try {
await host.reload(sessionId)
} catch (error) {
if (error instanceof Error && /Unable to reload missing extension session/.test(error.message)) {
// session gone; fall back to a fresh start with the original manifest
await host.start(manifest)
} else {
throw error
}
} Prevention
- Call host.getSession(id) before reload() to confirm the session is still live.
- Do not reload a session that was already stopped; use start(manifest) instead.
- Serialize stop/reload/start to avoid operating on a half-torn-down session.
When it happens
Trigger: Calling host.reload(sessionId) after the session was already stopped (host.stop removed it), was never started, or when passing a stale/typo sessionId.
Common situations: Calling reload on a session that was torn down by a previous stop() or cleanup. Holding a sessionId across a restart boundary. Using reload where start() on the manifest would be correct because the prior session is gone.
Related errors
- Unknown extension session: ${sessionId}
- Tamagotchi extension tool not found: ${key}
- Module `${moduleId}` was not found.
- Godot stage is not running.
- Godot stage bridge is not connected.
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/1ebf540e380cdd91.
Report an issue: GitHub.