{"record":{"id":"1911ac0f021b780f","repo":"linshenkx/prompt-optimizer","slug":"desktop-remote-storage-ipc-is-unavailable","errorCode":null,"errorMessage":"Desktop remote storage IPC is unavailable","messagePattern":"Desktop remote storage IPC is unavailable","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/ui/src/utils/remote-backup.ts","lineNumber":1535,"sourceCode":"  async getText(path: string): Promise<string> {\n    return this.invoke<string>('getText', { path })\n  }\n\n  async list(prefix: string): Promise<RemoteObjectEntry[]> {\n    return this.invoke<RemoteObjectEntry[]>('list', { path: prefix })\n  }\n\n  async delete(path: string): Promise<void> {\n    await this.invoke<null>('delete', { path })\n  }\n\n  private async invoke<T>(\n    operation: RemoteStorageIpcOperation,\n    input: Omit<RemoteStorageIpcRequest, 'provider' | 'operation'>,\n  ): Promise<T> {\n    const api = typeof window !== 'undefined' ? window.electronAPI?.remoteStorage : undefined\n    if (!api) {\n      throw new Error('Desktop remote storage IPC is unavailable')\n    }\n    return api.invoke<T>({\n      provider: cloneRemoteBackupProviderConfig(this.config),\n      operation,\n      ...input,\n    })\n  }\n}\n\nclass S3CompatibleRemoteObjectStore extends BaseRemoteObjectStore {\n  provider: RemoteBackupProviderKind = 's3-compatible'\n  private readonly client: S3Client\n\n  constructor(private readonly config: Extract<RemoteBackupProviderConfig, { kind: 's3-compatible' }>) {\n    super()\n    this.assertConfigured()\n    this.client = new S3Client({\n      endpoint: config.endpoint,","sourceCodeStart":1517,"sourceCodeEnd":1553,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/ui/src/utils/remote-backup.ts#L1517-L1553","documentation":"DesktopIpcRemoteObjectStore routes all operations through window.electronAPI.remoteStorage; if that preload bridge is missing it throws. This happens when web code runs outside the Electron desktop shell but the runtime flag says 'desktop'.","triggerScenarios":"runtime === 'desktop' passed to createRemoteObjectStore while window.electronAPI?.remoteStorage is undefined — running the UI in a plain browser, an outdated desktop build without the remoteStorage preload, or the preload script failed to inject.","commonSituations":"Opening the web bundle with a stale 'desktop' runtime flag; upgrading the web package without upgrading the Electron shell; preload script error suppressing electronAPI.","solutions":["Ensure the app actually runs inside the matching Electron desktop build (update the desktop app)","Verify the preload script exposes remoteStorage on window.electronAPI","Don't force runtime='desktop' when running in a browser — pass 'web'"],"exampleFix":"// before\nconst store = createRemoteObjectStore(cfg, 'desktop')\n// after\nconst runtime = window.electronAPI ? 'desktop' : 'web'\nconst store = createRemoteObjectStore(cfg, runtime)","handlingStrategy":"validation","validationCode":"const runtime = typeof window !== 'undefined' && window.electronAPI?.remoteStorage ? 'desktop' : 'web'","typeGuard":"const hasRemoteStorageIpc = (): boolean => Boolean((window as any)?.electronAPI?.remoteStorage)","tryCatchPattern":"catch (e) { if ((e as Error).message.includes('IPC is unavailable')) promptAppUpdate(); else throw e }","preventionTips":["Detect runtime from the bridge, not a hardcoded flag","Keep web and desktop builds in lockstep"],"tags":["electron","ipc","preload","runtime-mismatch"],"backgroundTag":"ipc-bridge-unavailable","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}