actualbudget/actual · error · Error
applyAppUpdate not implemented in electron app
Error message
applyAppUpdate not implemented in electron app
What it means
The Electron preload bridge deliberately throws for `reload` and `applyAppUpdate` instead of providing implementations. `applyAppUpdate` exists on the browser `window.Actual` API to apply a pending service-worker update; the Electron desktop app updates itself through its own updater, so this stub signals that the browser-only method was called in the wrong environment.
Source
Thrown at packages/desktop-electron/preload.ts:109
},
moveBudgetDirectory: (
currentBudgetDirectory: string,
newDirectory: string,
) => {
return ipcRenderer.invoke(
'move-budget-directory',
currentBudgetDirectory,
newDirectory,
);
},
reload: async () => {
throw new Error('Reload not implemented in electron app');
},
applyAppUpdate: async () => {
throw new Error('applyAppUpdate not implemented in electron app');
},
} satisfies typeof global.Actual);
View on GitHub (pinned to d4334cb6e6)
Solutions
- Skip the update-apply UI flow when running under Electron (check for Electron environment before offering 'apply update')
- In Electron, let the app auto-update via the Electron updater path instead of calling applyAppUpdate
- If you truly need a no-op, wrap the call in try/catch and treat the throw as 'handled natively by desktop'
Example fix
// before
await window.Actual.applyAppUpdate();
// after
if (process.env.IS_ELECTRON) {
// Electron applies updates itself; nothing to do
} else {
await window.Actual.applyAppUpdate();
} Defensive patterns
Strategy: try-catch
Validate before calling
const isElectron = typeof process !== 'undefined' && process.env.IS_ELECTRON;
if (isElectron) throw new Error('applyAppUpdate unsupported in Electron'); Type guard
const supportsApplyUpdate = (a: unknown): a is { applyAppUpdate: () => Promise<void> } =>
typeof a === 'object' && a !== null && 'applyAppUpdate' in a; Try / catch
try {
await window.Actual.applyAppUpdate();
} catch (e) {
if (String(e).includes('applyAppUpdate not implemented')) {
// Electron handles updates natively; ignore
} else throw e;
} Prevention
- Branch update UI on platform (Electron vs browser) before calling the API
- Treat the browser-only methods of global.Actual as unavailable in the desktop build
- Cover release/update flows with e2e tests in both web and desktop targets
When it happens
Trigger: Calling `window.Actual.applyAppUpdate()` (or code in desktop-client that invokes it, e.g. the 'update available' toast flow) while running in the Electron app, because the code assumed the browser `global.Actual` API surface.
Common situations: Shared client code written for the web build being reused in the desktop build; a release-flow UI component rendering in Electron; a plugin or custom patch calling the API without checking the platform.
Related errors
- @actual-app/api requires a node version ${minimumNodeVersion
- Invalid ${source}: "${raw}". Expected "true", "false", "1",
- The environment variable `lootCoreScript` is not defined. Pl
- Failed to init the server bundle after all retries: ${String
- ACTUAL_DATA_DIR is not set
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/8027e86c4797ee26.
Report an issue: GitHub.