actualbudget/actual · error · CompileError
Can't cast ${expr.type} to date
Error message
Can't cast ${expr.type} to date What it means
castInput is asked to coerce a query expression to the `date` type, but the expression's type is not `date`, a string literal, a parameter, null, or `any` — the only castable source types. The compiler throws CompileError naming the offending source type. Only literal strings can be parsed into dates; typed fields like integers or booleans cannot.
Source
Thrown at packages/loot-core/src/server/aql/compiler.ts:275
if (type === 'boolean') {
return typed(0, 'boolean', { literal: true });
}
return expr;
}
// These are all things that can be safely casted automatically
if (type === 'date') {
if (expr.type === 'string') {
if (expr.literal) {
return parseDate(expr.value) || badDateFormat(expr.value, 'date');
} 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 },View on GitHub (pinned to d4334cb6e6)
Solutions
- Pass a value that is already a date-typed field or a date-parseable string literal (e.g. '2024-01-15')
- Check the field reference — you likely named a non-date column; use `date` instead
- Cast on your side first: convert the value to a 'YYYY-MM-DD' string before putting it in the query
- Remove the wrong argument from the date-typed function call and supply the correct date expression
Example fix
// before
q.filter({ date: { $gte: q('amount') } })
// after
q.filter({ date: { $gte: '2024-01-15' } }) Defensive patterns
Strategy: validation
Validate before calling
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
if (!(typeof v === 'string' && DATE_RE.test(v))) {
throw new Error('Expected YYYY-MM-DD date string, got: ' + typeof v);
} Type guard
function isDateLike(v) {
return typeof v === 'string' && /^\d{4}-\d{2}-\d{2}/.test(v);
} Try / catch
try {
runQuery(q.filter({ date: { $gte: input } }));
} catch (e) {
if (/Can't cast .* to date/.test(e.message)) {
throw new Error(`Bad date input: ${JSON.stringify(input)}`, { cause: e });
}
throw e;
} Prevention
- Only pass date-parseable string literals or date-typed fields into date slots
- Never route numeric/id/boolean fields into date arguments
- Validate user input date strings before building queries
When it happens
Trigger: Calling a query function/op whose schema declares a `date` argument while passing a value of another type, e.g. `date` (integer month index), `boolean`, `id`, `array`, or a non-literal string field. Reached via val(), compileFunction(), or compileOp() during query compilation.
Common situations: Passing an integer or amount field where a date is expected (e.g. comparing a transaction amount column to a date); passing a Date object already compiled to another type; mixing up field names so a non-date column lands in a date filter.
Related errors
- Can't cast ${expr.type} to date-month
- 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/67ef0135280d99c3.
Report an issue: GitHub.