moeru-ai/airi · error · Error
toolKit requires a host tool registry runtime.
Error message
toolKit requires a host tool registry runtime.
What it means
Thrown by toolKit.registerTool() when the ToolKitRuntime supplied by the host does not include a `tools` registry. The `tools` field is optional (`tools?: { register; registerToolsetPrompt }`), so a host that registered the toolKit API without providing a tool registry causes every registerTool call to fail at the runtime boundary.
Source
Thrown at packages/plugin-sdk-tamagotchi/src/tools/index.ts:292
*
* Expects:
* - The host provides tool registry APIs when creating the kit client
*
* Returns:
* - A client that registers LLM tools without depending on domain-specific kits
*/
export const toolKit = defineKit<ToolKitClient>({
id: 'kit.tool',
version: '1.0.0',
allowedExposePolicies: ['local-only', 'remote-observable'],
defaultExposePolicy: 'local-only',
createClient(runtime) {
const toolRuntime = runtime as ToolKitRuntime
return {
async registerTool(definition) {
if (!toolRuntime.tools) {
throw new Error('toolKit requires a host tool registry runtime.')
}
const isAvailable = definition.isAvailable
await toolRuntime.tools.register({
tool: {
id: definition.id,
title: definition.title,
description: definition.description,
activation: {
keywords: definition.activation?.keywords ?? [],
patterns: (definition.activation?.patterns ?? []).map(pattern => pattern.source),
},
parameters: await serializeToolParameters(definition.inputSchema),
},
availability: isAvailable,
execute: definition.execute,
})View on GitHub (pinned to 27111382b4)
Solutions
- Ensure the host contribution creating the toolKit client passes a `tools` object with register() and registerToolsetPrompt() bound to a TamagotchiToolRegistry.
- Verify the kit is registered via host.registerKitApi with the full ToolKitRuntime, not just the kit descriptor.
- If tool registration is optional for your host, call tryUse(toolKit) and check availability before registerTool.
Example fix
// before
host.registerKitApi({ id: 'kit.tool', createClient: rt => toolKit.createClient(rt) })
// after
const registry = new TamagotchiToolRegistry()
host.registerKitApi({
id: 'kit.tool',
createClient: rt => toolKit.createClient({ ...rt, tools: {
register: rec => registry.register({ ownerSessionId: rt.sessionId, ownerExtensionId: rt.extensionId, ...rec }),
registerToolsetPrompt: rec => registry.registerToolsetPrompt({ ownerSessionId: rt.sessionId, ownerExtensionId: rt.extensionId, ...rec }),
} }),
}) Defensive patterns
Strategy: validation
Validate before calling
const result = await module.kits.tryUse(toolKit)
if (!result.ok || !result.client) {
throw new Error('toolKit unavailable on this host')
}
// Only safe to call registerTool if the host advertised the tool registry;
// otherwise the kit client's registerTool will throw at runtime boundary. Type guard
import type { ToolKitRuntime } from './tools'
function hostProvidesToolRegistry(rt: ToolKitRuntime): rt is ToolKitRuntime & { tools: NonNullable<ToolKitRuntime['tools']> } {
return rt.tools !== undefined
} Try / catch
try {
await client.registerTool(definition)
} catch (error) {
if (error instanceof Error && /toolKit requires a host tool registry runtime/.test(error.message)) {
// host did not attach a TamagotchiToolRegistry; skip or queue registration
} else {
throw error
}
} Prevention
- In the host contribution that creates the toolKit client, always pass a `tools` registry object backed by TamagotchiToolRegistry.
- Use tryUse(toolKit) and inspect the result before registerTool when tool support is optional.
- Add an integration test that registers a tool right after host bootstrap to catch a missing registry early.
When it happens
Trigger: Calling module.kits.use(toolKit).registerTool(...) on a host where the kit client was created with a runtime object that has no `tools` property, or where the host contribution forgot to attach the TamagotchiToolRegistry-backed register function.
Common situations: A Tamagotchi host wires up the toolKit descriptor but does not pass a TamagotchiToolRegistry instance into the runtime. Common during host bootstrap, in tests that register the kit but skip the registry, or after refactoring the host contribution that owns tool registration.
Related errors
- gameletKit requires a host gamelet orchestration runtime.
- 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/1858e414914fb822.
Report an issue: GitHub.