moeru-ai/airi · error · Error

gameletKit requires a host gamelet orchestration runtime.

Error message

gameletKit requires a host gamelet orchestration runtime.

What it means

Thrown by requireOrchestration() when a gamelet handle method (open, configure, request, close, isOpen) is called but the host did not wire the optional `gamelets` orchestration runtime into the gameletKit client. The gamelet was mounted successfully (bindings runtime was present) but the host never provided the open/close/request implementation, so orchestration calls cannot be routed.

Source

Thrown at packages/plugin-sdk-tamagotchi/src/kits/gamelet/index.ts:128

      await gamelets.orchestration?.close(bindingId)
    },
  })

  if (options.init === undefined) {
    return handle
  }

  return {
    ...handle,
    init: options.init,
  }
}

export { gameletKit }

function requireOrchestration(gamelets: Awaited<ReturnType<typeof gameletKit.createClient>>): NonNullable<typeof gamelets.orchestration> {
  if (!gamelets.orchestration) {
    throw new Error(GAMELET_RUNTIME_UNAVAILABLE_MESSAGE)
  }

  return gamelets.orchestration
}

View on GitHub (pinned to 27111382b4)

Solutions

  1. Ensure the host contribution that creates the gameletKit client provides a `gamelets` object on the runtime with open, configure, request, close, and isOpen implementations.
  2. If orchestration is genuinely optional for your host, guard handle calls by checking whether orchestration is available before invoking open/configure/request/close/isOpen.
  3. Register a no-op or stub `gamelets` implementation during development so mount + handle calls do not throw.

Example fix

// before (host contribution omits gamelets)
registerKitApi({ id: 'kit.gamelet', createClient: () => gameletKit.createClient({ bindings: myBindings }) })

// after (host provides gamelets orchestration)
registerKitApi({
  id: 'kit.gamelet',
  createClient: () => gameletKit.createClient({
    bindings: myBindings,
    gamelets: {
      open: (id, payload) => myOrchestrator.open(id, payload),
      configure: (id, payload) => myOrchestrator.configure(id, payload),
      request: (id, payload, opts) => myOrchestrator.request(id, payload, opts),
      close: id => myOrchestrator.close(id),
      isOpen: id => myOrchestrator.isOpen(id),
    },
  }),
})
Defensive patterns

Strategy: type-guard

Validate before calling

const gamelets = await module.kits.use(gameletKit)
if (!gamelets.orchestration) {
  throw new Error('Host did not provide gamelet orchestration; cannot open/configure/request/close.')
}
await gamelets.orchestration.open(bindingId)

Type guard

function hasGameletOrchestration(
  gamelets: Awaited<ReturnType<typeof gameletKit.createClient>>,
): gamelets is { orchestration: NonNullable<typeof gamelets.orchestration> } {
  return gamelets.orchestration !== undefined
}

Try / catch

try {
  await handle.open()
} catch (error) {
  if (error instanceof Error && error.message === 'gameletKit requires a host gamelet orchestration runtime.') {
    // host did not wire orchestration; degrade gracefully
  } else {
    throw error
  }
}

Prevention

When it happens

Trigger: Calling any method on the GameletHandle returned by createGamelet() — handle.open(), handle.configure(), handle.request(), handle.close(), or handle.isOpen() — when the GameletKitRuntime passed to gameletKit.createClient had no `gamelets` field (it is optional: `orchestration?: GameletKitRuntime['gamelets']`).

Common situations: A Tamagotchi host registers the gameletKit with only a `bindings` binding implementation (enough for mount) but forgets to supply the `gamelets` orchestration handlers. Also happens in tests or minimal host stubs that only exercise mounting, or after a host refactor that split binding from orchestration but only wired the binding side.

Related errors


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