chatboxai/chatbox · error · Error

OAuth IPC is only available on desktop

Error message

OAuth IPC is only available on desktop

What it means

Thrown by getDefaultOAuthIpc() when the platform object does not expose an ipc invoker, meaning the code is running outside the Electron desktop environment (e.g. the web build). The desktop OAuth adapter depends on IPC to reach the main process's keychain/token-refresh logic; without it, OAuth refresh and persistence cannot function.

Source

Thrown at src/renderer/adapters/index.ts:133

        return apiRequestClient.post(options.url, options.headers || {}, options.body, {
          signal: options.signal,
          retry: options.retry,
          useProxy: options.useProxy,
        })
      }
      return apiRequestClient.get(options.url, options.headers || {}, {
        signal: options.signal,
        retry: options.retry,
        useProxy: options.useProxy,
      })
    },
  }
}

function getDefaultOAuthIpc(): OAuthIpcInvoker {
  const maybeDesktopPlatform = platform as unknown as { ipc?: OAuthIpcInvoker }
  if (!maybeDesktopPlatform.ipc) {
    throw new Error('OAuth IPC is only available on desktop')
  }
  return maybeDesktopPlatform.ipc
}

function createDesktopOAuthAdapter(oauthIpc?: OAuthIpcInvoker): OAuthAdapter {
  return {
    async refreshCredential(providerId: string, credential: OAuthCredentials): Promise<OAuthCredentials> {
      const ipc = oauthIpc ?? getDefaultOAuthIpc()
      const resultJson = await ipc.invoke(OAuthIpcChannels.REFRESH, providerId, JSON.stringify(credential))
      const result = JSON.parse(resultJson) as {
        success: boolean
        credentials?: OAuthCredentials
        error?: string
      }
      if (!result.success || !result.credentials) {
        throw new Error(result.error || `Failed to refresh OAuth credential for ${providerId}`)
      }
      return result.credentials

View on GitHub (pinned to 81571269ad)

Solutions

  1. Guard the OAuth refresh/persist call site with a platform check and show a user-facing message on web builds.
  2. Inject a mock ipc invoker when constructing the adapter in tests.
  3. Ensure the desktop preload script attaches window.electron.ipc before any renderer OAuth code runs.

Example fix

// before
const maybeDesktopPlatform = platform as unknown as { ipc?: OAuthIpcInvoker }
if (!maybeDesktopPlatform.ipc) {
  throw new Error('OAuth IPC is only available on desktop')
}

// after — caller checks capability before reaching this path
if (!isDesktopPlatform()) {
  throw new Error('OAuth token refresh is not supported in this build; re-authenticate manually.')
}
Defensive patterns

Strategy: validation

Validate before calling

function isDesktopPlatform(): boolean {
  const maybe = platform as unknown as { ipc?: unknown }
  return !!maybe.ipc
}
if (!isDesktopPlatform()) {
  throw new Error('OAuth token refresh is not supported in this build')
}

Type guard

function hasOAuthIpc(p: unknown): p is { ipc: OAuthIpcInvoker } {
  return !!p && typeof (p as any)?.ipc?.invoke === 'function'
}

Try / catch

let adapter: OAuthAdapter
try {
  adapter = createDesktopOAuthAdapter()
} catch (e) {
  if (e instanceof Error && /only available on desktop/i.test(e.message)) {
    adapter = createNoopOAuthAdapter() // or prompt re-auth
  } else throw e
}

Prevention

When it happens

Trigger: createDesktopOAuthAdapter() is called (or refreshCredential is invoked) in a non-desktop context where the injected platform lacks .ipc. This happens when the web build accidentally constructs the desktop adapter, or when platform was not initialized before the OAuth path runs.

Common situations: Running the web (browser) build that does not preload the Electron ipcRenderer bridge; a test harness that imports the adapter module without mocking platform; a refactored entry point that no longer injects the desktop platform shim.

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/45163a1c9caf1abd. Report an issue: GitHub.