{"record":{"id":"bb098d9fb1fd7e60","repo":"moeru-ai/airi","slug":"gameletkit-requires-a-host-gamelet-orchestration-r","errorCode":null,"errorMessage":"gameletKit requires a host gamelet orchestration runtime.","messagePattern":"gameletKit requires a host gamelet orchestration runtime\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/plugin-sdk-tamagotchi/src/kits/gamelet/index.ts","lineNumber":128,"sourceCode":"      await gamelets.orchestration?.close(bindingId)\n    },\n  })\n\n  if (options.init === undefined) {\n    return handle\n  }\n\n  return {\n    ...handle,\n    init: options.init,\n  }\n}\n\nexport { gameletKit }\n\nfunction requireOrchestration(gamelets: Awaited<ReturnType<typeof gameletKit.createClient>>): NonNullable<typeof gamelets.orchestration> {\n  if (!gamelets.orchestration) {\n    throw new Error(GAMELET_RUNTIME_UNAVAILABLE_MESSAGE)\n  }\n\n  return gamelets.orchestration\n}\n","sourceCodeStart":110,"sourceCodeEnd":133,"githubUrl":"https://github.com/moeru-ai/airi/blob/677329427f32468c74b17f3ec47eeca4e05bec65/packages/plugin-sdk-tamagotchi/src/kits/gamelet/index.ts#L110-L133","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run against the full tamagotchi host that provides the gamelet orchestration runtime.","If you maintain the host, supply the orchestration capability when creating the gamelet kit client so `gamelets.orchestration` is defined.","In portable code, guard lifecycle calls: use handle.isOpen only via orchestration presence — check `gamelets.orchestration` before calling open/request/close.","Dispose path already tolerates absence (subscriptions use gamelets.orchestration?.close), so mirror that optional-chaining style for any custom lifecycle logic."],"exampleFix":"// before\nawait handle.open() // throws: host has bindings but no orchestration\n\n// after\nif (gamelets.orchestration) {\n  await handle.open()\n} else {\n  // host cannot orchestrate gamelet windows; degrade gracefully\n}","handlingStrategy":"validation","validationCode":"const gamelets = await module.kits.use(gameletKit)\nconst orchestration = gamelets.orchestration\nif (!orchestration) {\n  // host cannot orchestrate gamelet windows; avoid handle.open/request/close\n} else {\n  await orchestration.open(bindingId, payload)\n}","typeGuard":"function hasGameletOrchestration<T extends { orchestration?: object }>(\n  gamelets: T,\n): gamelets is T & { orchestration: NonNullable<T['orchestration']> } {\n  return gamelets.orchestration != null\n}","tryCatchPattern":"try {\n  await handle.open()\n} catch (error) {\n  if (errorMessageFrom(error).includes('requires a host gamelet orchestration runtime')) {\n    // degrade: gamelet mounted but not orchestratable on this host\n    return\n  }\n  throw error\n}","preventionTips":["Check gamelets.orchestration right after kits.use and remember the capability for the handle's lifetime.","Mirror the SDK's own dispose path, which already optional-chains (gamelets.orchestration?.close), in your custom lifecycle code.","When building a host, provide both bindings and orchestration together so mount and lifecycle stay consistent."],"tags":["plugin-sdk","tamagotchi","gamelet","host-runtime","lifecycle"],"backgroundTag":"host-runtime-capability-missing","analyzedSha":"677329427f32468c74b17f3ec47eeca4e05bec65","analyzedAt":"2026-08-18T17:29:58.153Z","contentChangedAt":"2026-08-18T17:29:58.153Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}