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
- Check the server/app logs (captureException output) for the underlying original error.
- Verify the database file is not locked or corrupt; back up and repair if needed.
- Retry the import with a minimal dashboard file (one simple widget) to isolate the failing data.
- 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
- Keep the SQLite database healthy (no locks, enough disk space) before large imports.
- Test imports with a minimal one-widget file to isolate bad data.
- Monitor server logs via captureException/Sentry for the masked root cause.
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
- Error importing budget: ${result.error}
- Error importing budget: no budget was loaded
- zipMeta ? getUnsafeZipError(zipMeta) : error
- Transfer payee with account ID ${transferAccountId} not foun
- Bank with ID ${bankId} not found.
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/69621390bfc33391.
Report an issue: GitHub.