{"record":{"id":"6a83d757c5bcce4c","repo":"actualbudget/actual","slug":"invalid-cutoff-date-expected-a-valid-date-e-g-y","errorCode":null,"errorMessage":"Invalid cutoff date: expected a valid date (e.g. YYYY-MM-DD).","messagePattern":"Invalid cutoff date: expected a valid date \\(e\\.g\\. YYYY-MM-DD\\)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/accounts.ts","lineNumber":168,"sourceCode":"        opts,\n        async () => {\n          await api.deleteAccount(id);\n          printOutput({ success: true, id }, opts.format);\n        },\n        { mutates: true },\n      );\n    });\n\n  accounts\n    .command('balance <id>')\n    .description('Get account balance')\n    .option('--cutoff <date>', 'Cutoff date (YYYY-MM-DD)')\n    .action(async (id: string, cmdOpts) => {\n      let cutoff: Date | undefined;\n      if (cmdOpts.cutoff) {\n        const cutoffDate = new Date(cmdOpts.cutoff);\n        if (Number.isNaN(cutoffDate.getTime())) {\n          throw new Error(\n            'Invalid cutoff date: expected a valid date (e.g. YYYY-MM-DD).',\n          );\n        }\n        cutoff = cutoffDate;\n      }\n      const opts = program.opts();\n      await withConnection(\n        opts,\n        async () => {\n          const balance = await api.getAccountBalance(id, cutoff);\n          printOutput({ id, balance }, opts.format);\n        },\n        { mutates: false },\n      );\n    });\n}\n","sourceCodeStart":150,"sourceCodeEnd":185,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/cli/src/commands/accounts.ts#L150-L185","documentation":"The accounts `transactions` (or similar) command accepts --cutoff as a date. It parses with new Date() and rejects values that produce NaN time — i.e. anything not a parseable date like YYYY-MM-DD. The guard catches malformed dates such as '2024-13-45' or '31/02/2024'.","triggerScenarios":"Running the command with `--cutoff foo`, `--cutoff 2024-13-01`, `--cutoff 01/31/2024` in locales where that string fails to parse, or `--cutoff` followed by another flag so it received the wrong token.","commonSituations":"Non-ISO date formats from regional habit (DD/MM/YYYY); dates built from shell variables with wrong format; forgetting the space so --cutoff=2024-1-5 partial garbage; timezone edge strings like '2024-02-30' (invalid day).","solutions":["Pass an ISO date: --cutoff 2024-06-30.","Generate the date programmatically: $(date -I) or $(date +%F) in shell.","Validate the date in the calling script before invoking the CLI.","If a full ISO timestamp is desired, it also parses — but prefer plain YYYY-MM-DD for consistency."],"exampleFix":"// before\nactual accounts transactions acct_1 --cutoff 30/06/2024\n// after\nactual accounts transactions acct_1 --cutoff \"$(date -d '30 days ago' +%F)\"","handlingStrategy":"validation","validationCode":"function isValidIsoDate(s: string): boolean {\n  return /^\\d{4}-\\d{2}-\\d{2}$/.test(s) && !Number.isNaN(new Date(s + 'T00:00:00Z').getTime());\n}\nif (!isValidIsoDate(cutoffArg)) throw new Error(`Bad --cutoff: ${cutoffArg}`);","typeGuard":"function isIsoDateString(v: unknown): v is string {\n  return typeof v === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(v) && !Number.isNaN(new Date(v + 'T00:00:00Z').getTime());\n}","tryCatchPattern":"try {\n  await runCli(['accounts', 'transactions', id, '--cutoff', cutoff]);\n} catch (e) {\n  if (String(e.message).includes('Invalid cutoff date')) {\n    console.error('Use YYYY-MM-DD, e.g. --cutoff 2024-06-30');\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Always use ISO YYYY-MM-DD format for date flags.","Generate dates with `date +%F` / `date -I` instead of hand-writing them.","Reject locale formats (DD/MM/YYYY) in wrapper scripts.","Beware shell separators: keep --cutoff and its value as separate tokens."],"tags":["cli","validation","date","arguments"],"backgroundTag":"invalid-date-argument","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}