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
- Inspect and correct the transport object so kind is an exact union literal ('in-memory' for web today).
- Validate config-derived kinds against a literal allowlist before calling createPluginContext.
- Deduplicate plugin-sdk versions in the workspace so both sides share one union.
- 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
- Validate any config-derived transport with a literal allowlist before use.
- Keep host and plugins on the same plugin-sdk version so the kind union matches.
- Prefer 'in-memory' literals (as const) over string-built kinds.
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
- Unknown plugin transport kind.
- Electron transport is not available in web runtime.
- Electron transport is not implemented yet.
- Node worker transport is not available in web runtime.
- Node worker transport is not implemented yet.
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)