{"record":{"id":"67ef0135280d99c3","repo":"actualbudget/actual","slug":"can-t-cast-expr-type-to-date","errorCode":null,"errorMessage":"Can't cast ${expr.type} to date","messagePattern":"Can't cast (.+?) to date","errorType":"exception","errorClass":"CompileError","httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/aql/compiler.ts","lineNumber":275,"sourceCode":"    if (type === 'boolean') {\n      return typed(0, 'boolean', { literal: true });\n    }\n    return expr;\n  }\n\n  // These are all things that can be safely casted automatically\n  if (type === 'date') {\n    if (expr.type === 'string') {\n      if (expr.literal) {\n        return parseDate(expr.value) || badDateFormat(expr.value, 'date');\n      } else {\n        throw new CompileError(\n          'Casting string fields to dates is not supported',\n        );\n      }\n    }\n\n    throw new CompileError(`Can't cast ${expr.type} to date`);\n  } else if (type === 'date-month') {\n    let expr2;\n    if (expr.type === 'date') {\n      expr2 = expr;\n    } else if (expr.type === 'string' || expr.type === 'any') {\n      expr2 =\n        parseMonth(expr.value) ||\n        parseDate(expr.value) ||\n        badDateFormat(expr.value, 'date-month');\n    } else {\n      throw new CompileError(`Can't cast ${expr.type} to date-month`);\n    }\n\n    if (expr2.literal) {\n      return typed(\n        dateToInt(expr2.value.toString().slice(0, 6)),\n        'date-month',\n        { literal: true },","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/aql/compiler.ts#L257-L293","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nq.filter({ date: { $gte: q('amount') } })\n// after\nq.filter({ date: { $gte: '2024-01-15' } })","handlingStrategy":"validation","validationCode":"const DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\nif (!(typeof v === 'string' && DATE_RE.test(v))) {\n  throw new Error('Expected YYYY-MM-DD date string, got: ' + typeof v);\n}","typeGuard":"function isDateLike(v) {\n  return typeof v === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(v);\n}","tryCatchPattern":"try {\n  runQuery(q.filter({ date: { $gte: input } }));\n} catch (e) {\n  if (/Can't cast .* to date/.test(e.message)) {\n    throw new Error(`Bad date input: ${JSON.stringify(input)}`, { cause: e });\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["aql","query-compiler","type-cast","dates"],"backgroundTag":"aql-type-cast-error","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}