{"record":{"id":"c30be171f69519f9","repo":"actualbudget/actual","slug":"actual-data-dir-env-variable-is-required","errorCode":null,"errorMessage":"ACTUAL_DATA_DIR env variable is required","messagePattern":"ACTUAL_DATA_DIR env variable is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/loot-core/src/platform/server/fs/index.electron.ts","lineNumber":28,"sourceCode":"export { getDocumentDir, getBudgetDir, _setDocumentDir } from './shared';\n\nlet rootPath = path.join(__dirname, '..', '..', '..', '..');\n\nswitch (path.basename(__filename)) {\n  case 'bundle.desktop.js': // electron app\n    rootPath = path.join(__dirname, '..', '..');\n    break;\n  default:\n    break;\n}\n\nexport const init: typeof T.init = async () => {\n  // Nothing to do\n};\n\nexport const getDataDir: typeof T.getDataDir = () => {\n  if (!process.env.ACTUAL_DATA_DIR) {\n    throw new Error('ACTUAL_DATA_DIR env variable is required');\n  }\n  return process.env.ACTUAL_DATA_DIR;\n};\n\nexport const bundledDatabasePath: typeof T.bundledDatabasePath = path.join(\n  rootPath,\n  'default-db.sqlite',\n);\n\nexport const migrationsPath: typeof T.migrationsPath = path.join(\n  rootPath,\n  'migrations',\n);\n\nexport const demoBudgetPath: typeof T.demoBudgetPath = path.join(\n  rootPath,\n  'demo-budget',\n);","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/platform/server/fs/index.electron.ts#L10-L46","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set `ACTUAL_DATA_DIR` in the Electron main process (typically `app.getPath('userData')`) before lazy-loading the backend bundle","Launch via the app's standard scripts that configure the environment","In tests, assign `process.env.ACTUAL_DATA_DIR = os.tmpdir()` in setup"],"exampleFix":"// before\nconst { initApp } = await import(process.env.lootCoreScript);\n// after\nprocess.env.ACTUAL_DATA_DIR ??= app.getPath('userData');\nconst { initApp } = await import(process.env.lootCoreScript);","handlingStrategy":"validation","validationCode":"if (!process.env.ACTUAL_DATA_DIR) {\n  throw new Error('Initialize ACTUAL_DATA_DIR (e.g. app.getPath(userData)) before using electron fs.');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const dir = getDataDir();\n} catch (e) {\n  if (String(e).includes('ACTUAL_DATA_DIR')) {\n    process.env.ACTUAL_DATA_DIR = app.getPath('userData');\n  } else throw e;\n}","preventionTips":["Configure the env var in the main process before importing the server bundle","Never launch the packaged backend with a bare `electron .` outside the standard entry","Add a startup assertion that the data dir exists and is writable"],"tags":["electron","env-var","fs"],"backgroundTag":"missing-env-var","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}