moeru-ai/airi · error · Error

Kit `${kitId}` is not registered.

Error message

Kit `${kitId}` is not registered.

What it means

Thrown by assertKitAvailableForRuntime() when the kitId referenced by a binding operation is not present in the host's KitRegistryService. The host cannot announce a binding for a kit it does not know about, so it fails fast before creating any module record.

Source

Thrown at packages/plugin-sdk/src/plugin-host/core.ts:571

    }
    await this.cleanupExtensionSessionModules(session)
    await session.subscriptions.dispose()
    this.extensionSessionService.remove(session.id)
  }

  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) {

View on GitHub (pinned to 27111382b4)

Solutions

  1. Register the kit descriptor via host.registerKit(kitDescriptor) (or a host contribution's install context) before extensions announce bindings against it.
  2. Verify the kitId string exactly matches the kit's declared id (e.g. 'kit.gamelet', not 'gamelet').
  3. Use host.getKit(kitId) or host.listKits() to confirm registration before announcing.

Example fix

// before
await host.announceBinding(sessionId, { kitId: 'kit.gamelet', ... }) // kit not registered

// after
host.registerKit({ kitId: 'kit.gamelet', runtimes: ['electron'], capabilities: [] })
await host.announceBinding(sessionId, { kitId: 'kit.gamelet', ... })
Defensive patterns

Strategy: validation

Validate before calling

const kit = host.getKit(kitId)
if (!kit) {
  throw new Error(`Kit '${kitId}' is not registered. Register it via host.registerKit(...) first.`)
}
host.announceBinding(sessionId, { kitId, ... })

Type guard

function isKitRegistered(host: ExtensionHost, kitId: string): boolean {
  return host.getKit(kitId) !== undefined
}

Try / catch

try {
  host.announceBinding(sessionId, { kitId, ... })
} catch (error) {
  if (error instanceof Error && /is not registered/.test(error.message)) {
    // register the kit descriptor before retrying the binding
  } else {
    throw error
  }
}

Prevention

When it happens

Trigger: Calling host.announceBinding(sessionId, { kitId, ... }) or host.bindExtensionKitModule(sessionId, { kitId, ... }) with a kitId that was never registered via host.registerKit() / the install context's registerKit.

Common situations: The host contribution that registers the kit (e.g. gameletKit descriptor via registerKit) was not installed before the extension tried to announce a binding. A typo in the kitId. The kit was unregistered before the binding call.

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/98f7f14d10eecfcb. Report an issue: GitHub.