moeru-ai/airi · warning · Error
Plugin host debug bridge is not available in this runtime.
Error message
Plugin host debug bridge is not available in this runtime.
What it means
The shared plugin-host devtools store wraps every action in withBridge, which requires a PluginHostDebugBridge registered via setBridge by the renderer bootstrap (it wires Eventa invoke functions from the Electron main process). When bridge.value is unset — because the runtime never ran that bootstrap or the page opened before registration — every debug action throws this availability error and records it in error.value.
Source
Thrown at packages/stage-ui/src/stores/devtools/plugin-host-debug.ts:141
refreshedAt.value = snapshot.refreshedAt
}
async function withBridge<T>(run: (activeBridge: PluginHostDebugBridge) => Promise<T>) {
// Single guard/flow wrapper for every debug action.
//
// What it does:
// 1) Runtime gate: blocks actions until bridge is registered.
// 2) Loading lifecycle: toggles `loading` in a centralized place.
// 3) Error normalization: stores user-facing error text for the debug page.
//
// Why debug store needs this:
// - Debug actions are async IPC calls and may fail for runtime/setup reasons.
// - A shared wrapper avoids duplicated try/catch/loading logic across each action.
// - It gives deterministic UI behavior (same errors/spinner semantics for all commands).
if (!bridge.value) {
const message = 'Plugin host debug bridge is not available in this runtime.'
error.value = message
throw new Error(message)
}
loading.value = true
clearError()
try {
return await run(bridge.value)
}
catch (cause) {
error.value = errorMessageFrom(cause) ?? 'Plugin host debug request failed.'
throw cause
}
finally {
loading.value = false
}
}
async function refreshRegistry() {
const nextRegistry = await withBridge(activeBridge => activeBridge.list())View on GitHub (pinned to f679616c34)
Solutions
- Use the plugin-host devtools page inside stage-tamagotchi (Electron), where the bridge is registered.
- Gate actions/UI on the store's isAvailable computed instead of calling and catching.
- Ensure the renderer bootstrap calls setBridge before devtools routes can mount.
- In tests, register a mock bridge via setBridge before invoking actions.
Example fix
// before
async function onInspect() {
await pluginHostDebug.refreshInspection()
}
// after
async function onInspect() {
if (!pluginHostDebug.isAvailable) {
toast.info('Plugin host debug is only available in the desktop runtime')
return
}
await pluginHostDebug.refreshInspection()
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!pluginHostDebug.isAvailable) {
toast.info('Plugin host debug requires the desktop (Electron) runtime')
return
}
await pluginHostDebug.refreshRegistry() Type guard
// The store already exposes the guard: isAvailable === Boolean(bridge)
function canUsePluginHostDebug(store: ReturnType<typeof usePluginHostDebugStore>): boolean {
return store.isAvailable
} Try / catch
try {
await pluginHostDebug.refreshInspection()
}
catch (error) {
// error.value already carries the user-facing text set by withBridge
if (!pluginHostDebug.isAvailable)
return // expected outside Electron; do not alarm the user
console.error(errorMessageFrom(error))
} Prevention
- Gate devtools routes/actions on isAvailable rather than calling and catching.
- Ensure the renderer bootstrap registers the bridge (setBridge) before devtools mount.
- Register a mock bridge in tests via setBridge before invoking actions.
- After HMR, re-run the bootstrap that calls setBridge if actions start failing.
When it happens
Trigger: Opening the plugin-host devtools page in a non-Electron runtime (stage-web, unit tests) where no IPC bridge exists; calling debug actions before the renderer bootstrap called setBridge; hot-reload losing the bridge registration; opening the page in an environment whose main process lacks the plugin host service.
Common situations: Reusing the shared devtools page outside stage-tamagotchi; race between route mount and bridge registration during startup; tests instantiating the store without registering a mock bridge.
Related errors
- initScreenCaptureForMain must be called before calling initS
- timeout must be a positive finite number
- Electron ipcRenderer is not available. Pass it explicitly to
- MCP tools are not available in this runtime.
- Electron IPC is not available in this renderer context
AI-assisted analysis of moeru-ai/airi@f679616c34 (2026-08-18).
Data as JSON: /api/errors/e5f79483f26a4b64.
Report an issue: GitHub.