moeru-ai/airi · error · Error
Kit `${kitId}` is not available for runtime `${runtime}`.
Error message
Kit `${kitId}` is not available for runtime `${runtime}`. What it means
Thrown by assertKitAvailableForRuntime() when the kit exists in the registry but its `runtimes` array does not include the runtime of the current session (or the host default runtime). This prevents binding a kit to a runtime it was not declared to support.
Source
Thrown at packages/plugin-sdk/src/plugin-host/core.ts:575
}
private getModuleOrThrow(moduleId: string) {
const module = this.modules.get(moduleId)
if (!module) {
throw new Error(`Module \`${moduleId}\` was not found.`)
}
return module
}
private assertKitAvailableForRuntime(kitId: string, runtime: PluginRuntime) {
const kit = this.kits.get(kitId)
if (!kit) {
throw new Error(`Kit \`${kitId}\` is not registered.`)
}
if (!kit.runtimes.includes(runtime)) {
throw new Error(`Kit \`${kitId}\` is not available for runtime \`${runtime}\`.`)
}
return kit
}
listSessions() {
return this.extensionSessionService.list()
}
getSession(sessionId: string) {
return this.extensionSessionService.get(sessionId)
}
registerKit(kit: KitDescriptor) {
return this.kits.register(kit)
}
unregisterKit(kitId: string) {View on GitHub (pinned to 27111382b4)
Solutions
- Add the target runtime to the kit descriptor's runtimes array when registering it (e.g. [...runtimes, 'electron']).
- Construct the ExtensionHost with the matching runtime (new ExtensionHost({ runtime: 'web' })) if the kit only supports that runtime.
- Pass options.runtime to host.start(manifest, { runtime }) so the session uses a runtime the kit supports.
Example fix
// before — kit only declares web, host defaults to electron
host.registerKit({ kitId: 'kit.gamelet', runtimes: ['web'], capabilities: [] })
host.announceBinding(sessionId, { kitId: 'kit.gamelet', ... }) // session runtime is 'electron'
// after — align runtimes
host.registerKit({ kitId: 'kit.gamelet', runtimes: ['web', 'electron'], capabilities: [] }) Defensive patterns
Strategy: validation
Validate before calling
const kit = host.getKit(kitId)
if (!kit) throw new Error(`Kit '${kitId}' not registered`)
const targetRuntime = session.runtime ?? 'electron'
if (!kit.runtimes.includes(targetRuntime)) {
throw new Error(`Kit '${kitId}' does not support runtime '${targetRuntime}'`)
}
host.announceBinding(sessionId, { kitId, ... }) Type guard
function kitSupportsRuntime(kit: { runtimes: string[] }, runtime: string): boolean {
return kit.runtimes.includes(runtime)
} Try / catch
try {
host.announceBinding(sessionId, { kitId, ... })
} catch (error) {
if (error instanceof Error && /not available for runtime/.test(error.message)) {
// widen the kit's runtimes or switch the session/host runtime
} else {
throw error
}
} Prevention
- When registering a kit, include every runtime the host may run as in the runtimes array.
- Keep the host constructor runtime (or per-start runtime) aligned with the kits you bind.
- Test kit binding under each runtime the kit claims to support.
When it happens
Trigger: Calling announceBinding or bindExtensionKitModule where the session.runtime (or host default `this.runtime`, which defaults to 'electron') is not in the kit descriptor's runtimes list. E.g. a kit declared with runtimes: ['web'] but the host/session runtime is 'electron'.
Common situations: Kit descriptor was registered with a restrictive runtimes list (e.g. only ['web']) but the host runs as 'electron' (the default). Or a node-runtime test tries to use an electron-only kit. Mismatched runtime between host constructor (options.runtime) and kit declaration.
Related errors
- Kit `${kitId}` is not registered.
- Unknown tool: ${tool}
- skip() cannot be mixed with other tool calls in the same scr
- Action limit exceeded: max ${this.maxActionsPerTurn} actions
- No WebSocket constructor is available. Pass `wsConstructor`
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/cbbaf4564274de3f.
Report an issue: GitHub.