{"record":{"id":"9794aed8719cdedd","repo":"actualbudget/actual","slug":"sync-id-is-required-for-sync-flag-set-sync-i","errorCode":null,"errorMessage":"Sync ID is required for sync ${flag}. Set --sync-id or ACTUAL_SYNC_ID.","messagePattern":"Sync ID is required for sync (.+?)\\. Set --sync-id or ACTUAL_SYNC_ID\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/sync.ts","lineNumber":24,"sourceCode":"import { CACHE_FILE_NAME, getMetaDir, readCacheState } from '#cache';\nimport type { CliConfig } from '#config';\nimport { resolveConfig } from '#config';\nimport { withConnection } from '#connection';\nimport { acquireExclusive } from '#lock';\nimport { printOutput } from '#output';\n\ntype SyncCmdOpts = {\n  status?: boolean;\n  clear?: boolean;\n};\n\nasync function requireSyncIdAndMeta(\n  opts: Record<string, unknown>,\n  flag: string,\n): Promise<{ config: CliConfig; meta: string }> {\n  const config = await resolveConfig(opts);\n  if (!config.syncId) {\n    throw new Error(\n      `Sync ID is required for sync ${flag}. Set --sync-id or ACTUAL_SYNC_ID.`,\n    );\n  }\n  return { config, meta: getMetaDir(config.dataDir, config.syncId) };\n}\n\nexport function registerSyncCommand(program: Command) {\n  program\n    .command('sync')\n    .description(\n      'Sync the local cached budget with the server, print cache status, or clear the cache',\n    )\n    .option('--status', 'Print cache status without syncing', false)\n    .option(\n      '--clear',\n      'Delete the local cache; next command re-downloads',\n      false,\n    )","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/cli/src/commands/sync.ts#L6-L42","documentation":"The `actual sync <flag>` commands (e.g. --download or --upload) synchronize a specific budget identified by a sync ID. requireSyncIdAndMeta resolves the CLI config and throws when neither the --sync-id flag nor the ACTUAL_SYNC_ID environment variable provides one. No sync target can be determined, so the operation aborts before connecting.","triggerScenarios":"Running `actual sync --download` without --sync-id and with ACTUAL_SYNC_ID unset in the environment; ACTUAL_SYNC_ID set only in an interactive shell profile but the command runs from cron/CI; a config file that omits the syncId key.","commonSituations":"CI pipelines missing env vars; running sync on a machine where the budget was never downloaded; forgetting that sync IDs are per-budget and changing machines.","solutions":["Pass the budget's sync ID explicitly: `actual sync --download --sync-id <id>`","Export ACTUAL_SYNC_ID=<id> in your shell profile or CI environment","Find the sync ID from the budget file or server (the ID of the budget you downloaded with `actual download`)","Set syncId in the CLI config file so all commands inherit it"],"exampleFix":"// before\nactual sync --download\n\n// after\nexport ACTUAL_SYNC_ID=\"a1b2c3d4-...\"\nactual sync --download\n# or\nactual sync --download --sync-id \"a1b2c3d4-...\"","handlingStrategy":"validation","validationCode":"const syncId = process.env.ACTUAL_SYNC_ID ?? flags.syncId;\nif (!syncId) {\n  throw new Error('Set ACTUAL_SYNC_ID or pass --sync-id before running `actual sync`');\n}","typeGuard":"function hasSyncTarget(o: { syncId?: string }): o is { syncId: string } {\n  return typeof o.syncId === 'string' && o.syncId.length > 0;\n}","tryCatchPattern":"try {\n  await run(['actual', 'sync', '--download']);\n} catch (e) {\n  if (String(e.message).includes('Sync ID is required')) {\n    console.error('Provide --sync-id <id> or export ACTUAL_SYNC_ID=<id>');\n  } else throw e;\n}","preventionTips":["Set ACTUAL_SYNC_ID in CI secrets and shell profiles, not just the interactive shell","Record the budget's sync ID when you first `actual download` it","Put syncId in the CLI config file for machine-level defaults"],"tags":["cli","sync","missing-argument","environment-variable"],"backgroundTag":"missing-required-identifier","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}