actualbudget/actual · error · CompileError
Can't cast ${expr.type} to date-month
Error message
Can't cast ${expr.type} to date-month What it means
castInput needs a `date-month` value (YYYY-MM). Accepted sources are `date`, `string`, and `any`; anything else (integer, boolean, id, array, etc.) cannot be cast and throws. Unlike `date`, non-literal string fields ARE allowed here via SQL SUBSTR, so the failure is limited to genuinely uncastable types.
Source
Thrown at packages/loot-core/src/server/aql/compiler.ts:286
} else {
throw new CompileError(
'Casting string fields to dates is not supported',
);
}
}
throw new CompileError(`Can't cast ${expr.type} to date`);
} else if (type === 'date-month') {
let expr2;
if (expr.type === 'date') {
expr2 = expr;
} else if (expr.type === 'string' || expr.type === 'any') {
expr2 =
parseMonth(expr.value) ||
parseDate(expr.value) ||
badDateFormat(expr.value, 'date-month');
} else {
throw new CompileError(`Can't cast ${expr.type} to date-month`);
}
if (expr2.literal) {
return typed(
dateToInt(expr2.value.toString().slice(0, 6)),
'date-month',
{ literal: true },
);
} else {
return typed(
`CAST(SUBSTR(${expr2.value}, 1, 6) AS integer)`,
'date-month',
);
}
} else if (type === 'date-year') {
let expr2;
if (expr.type === 'date' || expr.type === 'date-month') {
expr2 = expr;View on GitHub (pinned to d4334cb6e6)
Solutions
- Pass a date-typed field or a string like '2024-01' or '2024-01-15' instead
- Verify the field name refers to a date column, not a numeric/id column
- Convert the value to a month string ('YYYY-MM') before querying
- Drop the invalid expression and rebuild the month filter around the `date` field
Example fix
// before
q.groupBy({ $month: { $field: 'account' } })
// after
q.groupBy({ $month: { $field: 'date' } }) Defensive patterns
Strategy: validation
Validate before calling
const MONTH_RE = /^\d{4}-\d{2}(-\d{2})?$/;
if (!(typeof v === 'string' && MONTH_RE.test(v))) {
throw new Error('Expected YYYY-MM or YYYY-MM-DD string');
} Type guard
function isMonthLike(v) {
return typeof v === 'string' && /^\d{4}-\d{2}(-\d{2})?$/.test(v);
} Try / catch
try {
runQuery(q.groupBy({ $month: { $field: field } }));
} catch (e) {
if (/Can't cast .* to date-month/.test(e.message)) {
throw new Error(`Field '${field}' is not a date; use the date column`, { cause: e });
}
throw e;
} Prevention
- Only reference the `date` field (or month strings) in $month expressions
- Check the schema field type before grouping/filtering by month
- Normalize month inputs to 'YYYY-MM' strings
When it happens
Trigger: Using a date-month function (e.g. month grouping/filters) with an expression typed as something other than date/string/any/param/null — commonly an integer, float, boolean, id, or array value.
Common situations: Grouping by month but passing an account id or numeric field instead of `date`; passing a rule value of the wrong type through the API; a schema mismatch after renaming fields.
Related errors
- Can't cast ${expr.type} to date
- Can't cast ${expr.type} to date-year
- Can't convert ${expr.type} to ${type}
- Table "${tableName}" does not exist in the schema
- Too few arguments
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/f5472fadc515c604.
Report an issue: GitHub.