linshenkx/prompt-optimizer · error · BaseError

GENERATION_FAILED

GENERATION_FAILED

Error message

ElectronImageServiceProxy can only be used in Electron renderer process

What it means

ElectronImageServiceProxy is a renderer-side IPC shim that requires the preload bridge exposed as `window.electronAPI`. Its constructor throws immediately (as GENERATION_FAILED) when instantiated outside an Electron renderer process or when the preload script did not expose the API.

Source

Thrown at packages/core/src/services/image/electron-proxy.ts:52

    addConfig: (config: ImageModelConfigInput) => Promise<void>
    updateConfig: (id: string, updates: Partial<ImageModelConfigInput>) => Promise<void>
    deleteConfig: (id: string) => Promise<void>
    getConfig: (id: string) => Promise<ImageModelConfig | null>
    getAllConfigs: () => Promise<ImageModelConfig[]>
    getEnabledConfigs: () => Promise<ImageModelConfig[]>
    exportData: () => Promise<unknown>
    importData: (data: unknown) => Promise<void>
    getDataType: () => Promise<string>
    validateData: (data: unknown) => Promise<boolean>
  }
}

export class ElectronImageServiceProxy implements IImageService {
  private electronAPI: ElectronAPI

  constructor() {
    if (typeof window === 'undefined' || !window.electronAPI) {
      throw new BaseError(IMAGE_ERROR_CODES.GENERATION_FAILED, 'ElectronImageServiceProxy can only be used in Electron renderer process')
    }
    this.electronAPI = (window as unknown as { electronAPI: ElectronAPI }).electronAPI
  }

  async generate(request: ImageRequest): Promise<ImageResult> {
    const safeReq = safeSerializeForIPC(request)
    return await this.electronAPI.image.generate(safeReq)
  }

  async generateText2Image(request: Text2ImageRequest): Promise<ImageResult> {
    const safeReq = safeSerializeForIPC(request)
    return await this.electronAPI.image.generateText2Image(safeReq)
  }

  async generateImage2Image(request: Image2ImageRequest): Promise<ImageResult> {
    const safeReq = safeSerializeForIPC(request)
    return await this.electronAPI.image.generateImage2Image(safeReq)
  }

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Only instantiate the proxy inside the Electron renderer after DOM load
  2. Ensure the preload script calls contextBridge.exposeInMainWorld('electronAPI', {...})
  3. In tests, mock window.electronAPI before constructing: (window as any).electronAPI = mockAPI
  4. In shared code, feature-detect: if (!window.electronAPI) use the direct service instead

Example fix

// before
const svc = new ElectronImageServiceProxy()

// after
function createImageService(): IImageService {
  if (typeof window !== 'undefined' && window.electronAPI) {
    return new ElectronImageServiceProxy()
  }
  return new ImageService(/* ... */)
}
Defensive patterns

Strategy: type-guard

Validate before calling

const canUseElectronProxy = typeof window !== 'undefined' && !!(window as any).electronAPI?.imageService

Type guard

function isElectronRenderer(w: unknown): w is Window & { electronAPI: ElectronAPI } {
  return typeof w !== 'undefined' && !!(w as any)?.electronAPI
}

Prevention

When it happens

Trigger: Constructing ElectronImageServiceProxy in a plain browser tab, in a Node/main process, in tests/jsdom, or in an Electron renderer where contextIsolation settings prevent window.electronAPI from being set.

Common situations: Unit tests importing the proxy without mocking window.electronAPI; preload script missing contextBridge.exposeInMainWorld('electronAPI', ...); sandbox or nodeIntegration misconfiguration; code shared between web and Electron builds.

Related errors


AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27). Data as JSON: /api/errors/e5a64909bc1535ba. Report an issue: GitHub.