actualbudget/actual · critical · Error

ACTUAL_DATA_DIR env variable is required

Error message

ACTUAL_DATA_DIR env variable is required

What it means

The Electron build of the server `fs` module resolves every file operation against `ACTUAL_DATA_DIR`. If the env var is unset, `getDataDir` throws because there is no safe default location for user data (budget files, sqlite DBs) in the desktop app.

Source

Thrown at packages/loot-core/src/platform/server/fs/index.electron.ts:28

export { getDocumentDir, getBudgetDir, _setDocumentDir } from './shared';

let rootPath = path.join(__dirname, '..', '..', '..', '..');

switch (path.basename(__filename)) {
  case 'bundle.desktop.js': // electron app
    rootPath = path.join(__dirname, '..', '..');
    break;
  default:
    break;
}

export const init: typeof T.init = async () => {
  // Nothing to do
};

export const getDataDir: typeof T.getDataDir = () => {
  if (!process.env.ACTUAL_DATA_DIR) {
    throw new Error('ACTUAL_DATA_DIR env variable is required');
  }
  return process.env.ACTUAL_DATA_DIR;
};

export const bundledDatabasePath: typeof T.bundledDatabasePath = path.join(
  rootPath,
  'default-db.sqlite',
);

export const migrationsPath: typeof T.migrationsPath = path.join(
  rootPath,
  'migrations',
);

export const demoBudgetPath: typeof T.demoBudgetPath = path.join(
  rootPath,
  'demo-budget',
);

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Set `ACTUAL_DATA_DIR` in the Electron main process (typically `app.getPath('userData')`) before lazy-loading the backend bundle
  2. Launch via the app's standard scripts that configure the environment
  3. In tests, assign `process.env.ACTUAL_DATA_DIR = os.tmpdir()` in setup

Example fix

// before
const { initApp } = await import(process.env.lootCoreScript);
// after
process.env.ACTUAL_DATA_DIR ??= app.getPath('userData');
const { initApp } = await import(process.env.lootCoreScript);
Defensive patterns

Strategy: validation

Validate before calling

if (!process.env.ACTUAL_DATA_DIR) {
  throw new Error('Initialize ACTUAL_DATA_DIR (e.g. app.getPath(userData)) before using electron fs.');
}

Try / catch

try {
  const dir = getDataDir();
} catch (e) {
  if (String(e).includes('ACTUAL_DATA_DIR')) {
    process.env.ACTUAL_DATA_DIR = app.getPath('userData');
  } else throw e;
}

Prevention

When it happens

Trigger: Any fs operation that routes through `getDataDir` (path resolution for budgets, backups, migrations) in the Electron backend when `process.env.ACTUAL_DATA_DIR` is undefined.

Common situations: Launching the packaged Electron backend outside its normal entry point; the main process failing to set the env var before importing the server bundle; test harnesses exercising `fs/index.electron.ts` directly.

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


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/c30be171f69519f9. Report an issue: GitHub.