moeru-ai/airi · info · Error

Electron transport is not available in web runtime.

Error message

Electron transport is not available in web runtime.

What it means

Thrown by `createPluginContext()` in the web runtime when `transport.kind === 'electron'`. Electron IPC transports require the Electron renderer bridge (`window.electron`), which does not exist in a plain web context, so the web runtime rejects it. This is an environment mismatch guard.

Source

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

 *
 * Expects:
 * - `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 27111382b4)

Solutions

  1. Use `createPluginContext({ kind: 'in-memory' })` for the web runtime; keep `electron` transport for the stage-tamagotchi renderer only.
  2. Detect the runtime (e.g. check for the Electron preload bridge) before selecting a transport kind.
  3. Verify the Electron preload bridge is injected before selecting the electron transport in renderer code.
  4. Audit shared config so transport selection is environment-aware.

Example fix

// before
const ctx = createPluginContext({ kind: 'electron' })

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

Strategy: type-guard

Validate before calling

const isElectron = typeof window !== 'undefined' && !!(window as any).electron
const kind = isElectron ? 'electron' : 'in-memory'
const ctx = createPluginContext({ kind })

Type guard

function hasElectronBridge(w: Window & typeof globalThis): boolean {
  return Boolean((w as unknown as { electron?: unknown }).electron)
}

function isWebSafeTransport(t: PluginTransport): boolean {
  return t.kind !== 'electron'
}

Try / catch

try {
  ctx = createPluginContext(transport)
} catch (e) {
  if (e instanceof Error && /not available in web runtime/i.test(e.message)) {
    ctx = createPluginContext({ kind: 'in-memory' })
  } else throw e
}

Prevention

When it happens

Trigger: Selecting the `electron` transport kind in a non-Electron web context. Occurs when Electron-targeted plugin host configuration is loaded in a regular browser build or when the Electron preload bridge is unavailable.

Common situations: Sharing plugin host config between the Electron (stage-tamagotchi) and web (stage-web) apps without conditioning on runtime; running the web app outside Electron while config still defaults to the electron transport; preload script not injected so the bridge is missing.

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/ced3c7e82156668d. Report an issue: GitHub.