moeru-ai/airi · error · Error

gameletKit requires a host gamelet orchestration runtime.

Error message

gameletKit requires a host gamelet orchestration runtime.

What it means

Gamelet handles created via createGamelet (packages/plugin-sdk-tamagotchi/src/kits/gamelet/index.ts) expose open/configure/request/close/isOpen, all of which route through requireOrchestration(gamelets). orchestration is an optional field on the gamelet kit client: it exists only when the host supplied a gamelet orchestration runtime (lifecycle management for mounted gamelets). requireOrchestration throws GAMELET_RUNTIME_UNAVAILABLE_MESSAGE when the field is absent, so calling any lifecycle method on a handle whose host cannot orchestrate gamelets fails fast. Note mount() itself may succeed (it needs bindings, not orchestration); only lifecycle calls require this capability.

Solutions

  1. Run against the full tamagotchi host that provides the gamelet orchestration runtime.
  2. If you maintain the host, supply the orchestration capability when creating the gamelet kit client so `gamelets.orchestration` is defined.
  3. In portable code, guard lifecycle calls: use handle.isOpen only via orchestration presence — check `gamelets.orchestration` before calling open/request/close.
  4. Dispose path already tolerates absence (subscriptions use gamelets.orchestration?.close), so mirror that optional-chaining style for any custom lifecycle logic.

Example fix

// before
await handle.open() // throws: host has bindings but no orchestration

// after
if (gamelets.orchestration) {
  await handle.open()
} else {
  // host cannot orchestrate gamelet windows; degrade gracefully
}
Defensive patterns

Strategy: validation

Validate before calling

const gamelets = await module.kits.use(gameletKit)
const orchestration = gamelets.orchestration
if (!orchestration) {
  // host cannot orchestrate gamelet windows; avoid handle.open/request/close
} else {
  await orchestration.open(bindingId, payload)
}

Type guard

function hasGameletOrchestration<T extends { orchestration?: object }>(
  gamelets: T,
): gamelets is T & { orchestration: NonNullable<T['orchestration']> } {
  return gamelets.orchestration != null
}

Try / catch

try {
  await handle.open()
} catch (error) {
  if (errorMessageFrom(error).includes('requires a host gamelet orchestration runtime')) {
    // degrade: gamelet mounted but not orchestratable on this host
    return
  }
  throw error
}

Prevention

When it happens

Trigger: Calling handle.open(), handle.request(), handle.configure(), or handle.close() on a gamelet created against a host that provides bindings but not orchestration — e.g. a minimal/test host, or a host version where gamelet window orchestration is not implemented. mount works, then the first lifecycle call throws.

Common situations: Extension unit tests with a stub host that only implements bindings; hosts at different feature levels; code written against the full tamagotchi host then run under a slim embedded host.

Related errors


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

Appendix: 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 677329427f)