moeru-ai/airi · error · Error

Unknown plugin transport kind.

Error message

Unknown plugin transport kind.

What it means

Thrown by createPluginContext in the node runtime when transport.kind matches none of the known cases. The PluginTransport union covers in-memory, websocket, node-worker, electron, and web-worker; reaching default means the value is outside that union — typically a malformed object, an undefined kind, or a newer kind string passed to an older SDK version.

Solutions

  1. Log/inspect the actual transport object and fix the kind value to a literal member of the union ('in-memory' for node).
  2. Validate config-derived transports with a literal allowlist before calling createPluginContext.
  3. Align plugin-sdk versions across the workspace so both sides agree on the set of kinds.
  4. If you are extending PluginTransport with a new kind, add the case to the runtime switch instead of relying on default.

Example fix

// before
const ctx = createPluginContext(JSON.parse(process.env.PLUGIN_TRANSPORT!)) // { "kind": "inmemory" } -> default throw

// after
const KINDS = ['in-memory', 'websocket', 'node-worker', 'electron', 'web-worker'] as const
const raw = JSON.parse(process.env.PLUGIN_TRANSPORT!) as { kind?: string }
if (!KINDS.includes(raw.kind ?? '')) throw new Error(`Bad PLUGIN_TRANSPORT.kind: ${raw.kind}`)
const ctx = createPluginContext({ kind: 'in-memory' })
Defensive patterns

Strategy: validation

Validate before calling

const KINDS = ['in-memory', 'websocket', 'node-worker', 'electron', 'web-worker'] as const
type KnownKind = typeof KINDS[number]
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.') {
    // log the offending object and fix config; do not retry blindly
    console.error('transport =', transport)
  }
  throw error
}

Prevention

When it happens

Trigger: Passing { kind: undefined } or {} because the transport was built from unvalidated JSON/env config; a typo like 'inmemory' or 'in_memory'; a newer plugin-sdk peer passing a kind this host version does not know; spreading an object that lost the kind field.

Common situations: Transport chosen from environment variables or user config without validation; mixed plugin-sdk versions in a monorepo; refactoring that renames the discriminant field; serialization dropping the kind property.

Related errors


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

Appendix: source

Thrown at packages/plugin-sdk/src/plugin-host/runtimes/node/index.ts:37

 * - `transport` describes a transport supported by the node runtime
 *
 * Returns:
 * - A node-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 node runtime yet.')
    case 'node-worker':
      throw new Error('Node worker transport is not implemented yet.')
    case 'electron':
      throw new Error('Electron transport is not implemented yet.')
    case 'web-worker':
      throw new Error('Web worker transport is not available in node runtime.')
    default:
      throw new Error('Unknown plugin transport kind.')
  }
}

View on GitHub (pinned to 677329427f)