moeru-ai/airi · error · Error

Unknown plugin transport kind.

Error message

Unknown plugin transport kind.

What it means

Thrown by createPluginContext in the web runtime when transport.kind matches no case of the web switch (in-memory, websocket, web-worker, node-worker, electron). Hitting default means the discriminant is outside the PluginTransport union: undefined kind, a typo, or a kind string from a newer SDK passed to an older web host.

Solutions

  1. Inspect and correct the transport object so kind is an exact union literal ('in-memory' for web today).
  2. Validate config-derived kinds against a literal allowlist before calling createPluginContext.
  3. Deduplicate plugin-sdk versions in the workspace so both sides share one union.
  4. When adding a custom kind, extend the web switch rather than falling through to default.

Example fix

// before
const transport = { kind: 'In-Memory' } as any // typo -> default throw
const ctx = createPluginContext(transport)

// after
const transport = { kind: 'in-memory' } as const
const ctx = createPluginContext(transport)
Defensive patterns

Strategy: validation

Validate before calling

const KINDS = ['in-memory', 'websocket', 'node-worker', 'electron', 'web-worker'] as const
function parseTransport(raw: unknown): PluginTransport {
  const kind = (raw as { kind?: unknown })?.kind
  if (typeof kind !== 'string' || !(KINDS as readonly string[]).includes(kind)) {
    throw new Error(`Invalid transport kind: ${String(kind)}`)
  }
  return raw as PluginTransport
}

Type guard

const KNOWN_KINDS = ['in-memory', 'websocket', 'node-worker', 'electron', 'web-worker'] as const
const isKnownTransportKind = (value: unknown): value is (typeof KNOWN_KINDS)[number] =>
  typeof value === 'string' && (KNOWN_KINDS as readonly string[]).includes(value)

Try / catch

try {
  ctx = createPluginContext(transport)
} catch (error) {
  if (error instanceof Error && error.message === 'Unknown plugin transport kind.') {
    console.error('transport =', transport) // inspect and fix the discriminant
  }
  throw error
}

Prevention

When it happens

Trigger: Transport object parsed from JSON/config with a misspelled kind ('In-Memory', 'inmemory'); { kind } destructuring where kind is undefined; new transport kinds added by a newer plugin-sdk consumed by an older host build; serialized transport losing the kind field across postMessage.

Common situations: Config-driven transport selection without validation; mixed plugin-sdk versions between host and plugins; refactors renaming the discriminant; IPC/serialization dropping fields.

Related errors


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

Appendix: source

Thrown at packages/plugin-sdk/src/plugin-host/runtimes/web/index.ts:36

 * - `transport` describes a transport supported by the web runtime
 *
 * Returns:
 * - A web-compatible Eventa context, or throws if the transport is not implemented
 */
export function createPluginContext(transport: PluginTransport): EventContext<any, any> {
  switch (transport.kind) {
    case 'in-memory':
      return createContext()
    case 'websocket':
      throw new Error('WebSocket transport is not implemented for web runtime yet.')
    case 'web-worker':
      throw new Error('Web worker transport is not implemented yet.')
    case 'node-worker':
      throw new Error('Node worker transport is not available in web runtime.')
    case 'electron':
      throw new Error('Electron transport is not available in web runtime.')
    default:
      throw new Error('Unknown plugin transport kind.')
  }
}

View on GitHub (pinned to 677329427f)