actualbudget/actual · error · Error
ACTUAL_DATA_DIR is not set
Error message
ACTUAL_DATA_DIR is not set
What it means
`getDataDir` in the Electron window-state module reads `ACTUAL_DATA_DIR` to know where to persist window state (position/size) JSON. If the env var is missing it throws rather than guessing a directory, because the desktop app sets this variable during startup.
Source
Thrown at packages/desktop-electron/window-state.ts:15
import fs from 'fs';
import path from 'path';
import electron from 'electron';
import type { BrowserWindow } from 'electron';
type WindowState = Electron.Rectangle & {
isMaximized?: boolean;
isFullScreen?: boolean;
displayBounds?: Electron.Rectangle;
};
const getDataDir = () => {
if (!process.env.ACTUAL_DATA_DIR) {
throw new Error('ACTUAL_DATA_DIR is not set');
}
return process.env.ACTUAL_DATA_DIR;
};
async function loadState() {
let state: WindowState | undefined = undefined;
try {
state = JSON.parse(
fs.readFileSync(path.join(getDataDir(), 'window.json'), 'utf8'),
);
} catch {
console.log('Could not load window state');
}
return validateState(state);
}
View on GitHub (pinned to d4334cb6e6)
Solutions
- Set `ACTUAL_DATA_DIR` to the app's user-data directory (e.g. `app.getPath('userData')`) before loading the window-state module
- Launch the app via the standard scripts/builds that set the env var
- In tests, set `process.env.ACTUAL_DATA_DIR` to a temp directory in your setup fixture
Example fix
// before
import { loadState } from './window-state';
// after
process.env.ACTUAL_DATA_DIR ??= app.getPath('userData');
import { loadState } from './window-state'; Defensive patterns
Strategy: validation
Validate before calling
if (!process.env.ACTUAL_DATA_DIR) {
process.env.ACTUAL_DATA_DIR = require('electron').app.getPath('userData');
} Try / catch
try {
const state = loadState();
} catch (e) {
if (String(e).includes('ACTUAL_DATA_DIR is not set')) {
// fall back to defaults / re-set env and retry
} else throw e;
} Prevention
- Set ACTUAL_DATA_DIR at the very top of the main process entry, before other imports run
- Use app.getPath('userData') as the canonical value
- In tests, assign a temp dir in beforeEach
When it happens
Trigger: Calling `loadState()` or `saveState()` from `window-state.ts` when the Electron main process environment lacks `ACTUAL_DATA_DIR` — e.g. launching the app outside its normal launcher scripts.
Common situations: Running the electron main file directly with node/electron CLI; custom launchers or test harnesses that don't replicate the production env; refactors that call window-state functions before env setup.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- The environment variable `lootCoreScript` is not defined. Pl
- ACTUAL_DATA_DIR env variable is required
- applyAppUpdate not implemented in electron app
- Failed to init the server bundle after all retries: ${String
- Invalid token_expiration value: ${val}: value was "${val}"
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/9231d7180df25c18.
Report an issue: GitHub.