actualbudget/actual · error

internal-error

internal-error

Error message

Internal error occurred during import.

What it means

Any error thrown during import that is neither a SyntaxError nor a ValidationError is converted to `Error('Internal error occurred during import.', { cause: 'internal-error' })`, and the original error is reported via captureException. This masks DB/write failures behind a generic message.

Source

Thrown at packages/loot-core/src/server/dashboard/app.ts:349

              tombstone: false,
            }),
          ),
      ]);
    });

    return { status: 'ok' as const };
  } catch (err: unknown) {
    if (err instanceof Error) {
      err.message = 'Error importing file: ' + err.message;
      captureException(err);
    }
    if (err instanceof SyntaxError) {
      throw new Error('Invalid JSON file.', { cause: 'json-parse-error' });
    }
    if (err instanceof ValidationError) {
      throw new Error(err.message, { cause: 'validation-error' });
    }
    throw new Error('Internal error occurred during import.', {
      cause: 'internal-error',
    });
  }
}

export type DashboardHandlers = {
  'dashboard-create': typeof createDashboardPage;
  'dashboard-delete': typeof deleteDashboardPage;
  'dashboard-rename': typeof renameDashboardPage;
  'dashboard-update': typeof updateDashboard;
  'dashboard-update-widget': typeof updateDashboardWidget;
  'dashboard-reset': typeof resetDashboard;
  'dashboard-add-widget': typeof addDashboardWidget;
  'dashboard-remove-widget': typeof removeDashboardWidget;
  'dashboard-copy-widget': typeof copyDashboardWidget;
  'dashboard-import': typeof importDashboard;
};

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Check the server/app logs (captureException output) for the underlying original error.
  2. Verify the database file is not locked or corrupt; back up and repair if needed.
  3. Retry the import with a minimal dashboard file (one simple widget) to isolate the failing data.
  4. Upgrade Actual; if reproducible, file an issue with the sanitized import file.

Example fix

// before
await send('dashboard-import', { filePath: hugeMixedFile, dashboardPageId });
// after
try {
  await send('dashboard-import', { filePath: minimalFile, dashboardPageId });
} catch (e) {
  if (e.cause === 'internal-error') console.error('check server logs');
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await send('dashboard-import', { filePath, dashboardPageId });
} catch (e) {
  if (e.cause === 'internal-error') {
    // original error was sent to captureException; check server logs
    console.error('Import failed internally; inspect server logs and DB state.');
  }
}

Prevention

When it happens

Trigger: Database insert failures while writing imported widgets (constraint violations, locked DB), errors in addDashboardWidget/import internals, or any non-parse non-validation exception inside the try block.

Common situations: Corrupt or locked SQLite file; disk full; imported data violating DB constraints (e.g. duplicate ids or broken references in meta); running an old build against a newer export.

Related errors


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