actualbudget/actual · error · Error
No sync server set
Error message
No sync server set
What it means
saveMetadataPrefs (packages/loot-core/src/server/preferences/app.ts:220) throws this plain Error when it needs to push the budget name to the server (prefsToSet.budgetName with a cloudFileId present) but no sync server URL is configured — getServer()?.SYNC_SERVER is undefined. It typically means the client is running without a server base URL set (server-only mode URLs absent from the environment/config).
Source
Thrown at packages/loot-core/src/server/preferences/app.ts:220
? true
: notifyWhenUpdateIsAvailable, // default to true
};
}
async function saveMetadataPrefs(prefsToSet: MetadataPrefs) {
if (!prefsToSet) {
return 'ok';
}
const { cloudFileId } = _getMetadataPrefs();
// Need to sync the budget name on the server as well
if (prefsToSet.budgetName && cloudFileId) {
const userToken = await asyncStorage.getItem('user-token');
const syncServer = getServer()?.SYNC_SERVER;
if (!syncServer) {
throw new Error('No sync server set');
}
await post(syncServer + '/update-user-filename', {
token: userToken,
fileId: cloudFileId,
name: prefsToSet.budgetName,
});
}
await _saveMetadataPrefs(prefsToSet);
return 'ok';
}
async function loadMetadataPrefs(): Promise<MetadataPrefs> {
return _getMetadataPrefs();
}
async function saveServerPrefs({ prefs }: { prefs: Record<string, string> }) {View on GitHub (pinned to d4334cb6e6)
Solutions
- Configure the sync server URL so getServer().SYNC_SERVER is defined (set the server base URL in the sync-server config/environment serving the frontend).
- If you don't use sync, rename the budget without a cloudFileId (local-only budget).
- Restart the deployment after adding the server URL so the config propagates to the client.
- Verify with the deployed app that /update-user-filename is reachable once the URL is set.
Example fix
// before: frontend served without sync server configured (SYNC_SERVER undefined) // after: in sync-server config / environment // .env: ACTUAL_SERVER_URL=https://sync.example.com // restart sync-server so the client receives SYNC_SERVER in getServer()
Defensive patterns
Strategy: validation
Validate before calling
const syncServer = getServer()?.SYNC_SERVER;
if (prefsToSet.budgetName && cloudFileId && !syncServer) {
// don't attempt the rename sync; warn the user the server URL is not configured
logger.log('Skipping budget-name sync: no sync server configured');
return;
} Type guard
function hasSyncServer(cfg: unknown): cfg is { SYNC_SERVER: string } {
return typeof cfg === 'object' && cfg !== null && typeof (cfg as any).SYNC_SERVER === 'string' && (cfg as any).SYNC_SERVER.length > 0;
} Try / catch
try {
await savePrefs(prefsToSet);
} catch (e) {
if (e instanceof Error && e.message === 'No sync server set') {
// prompt the user to configure the server URL, or proceed without cloud rename
showConfigureServerDialog();
} else throw e;
} Prevention
- Set the sync server URL in the deployment config serving the frontend before users rename cloud budgets.
- Guard rename flows with a SYNC_SERVER existence check.
- For local-only budgets, ensure no cloudFileId is set so server sync is skipped.
- Document required environment variables (server URL) in self-hosting setup.
When it happens
Trigger: Renaming a budget (saving metadata with a new budgetName) while a cloudFileId exists, in a build where SYNC_SERVER is not configured — e.g. the web frontend served without the sync server URL configured, or a desktop build in local-only mode that somehow has a cloudFileId.
Common situations: Self-hosting the frontend without setting the sync server URL in the server config; missing ACTUAL_SERVER_URL-style environment variable; using a build of the app compiled without server endpoints; renamed cloud budgets after switching from a server-less deployment.
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
- Failed to get server config.
- No sync server configured.
- No sync server configured.
- NOT_CONFIGURED
- @actual-app/api requires a node version ${minimumNodeVersion
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/b58dee7b293e20f0.
Report an issue: GitHub.