{"record":{"id":"9857c6096b782efb","repo":"actualbudget/actual","slug":"query-value-cannot-be-undefined","errorCode":null,"errorMessage":"Query value cannot be undefined","messagePattern":"Query value cannot be undefined","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/aql/schema-helpers.ts","lineNumber":13,"sourceCode":"import { fromDateRepr, toDateRepr } from '#server/models';\n// @ts-strict-ignore\nimport { dayFromDate } from '#shared/months';\n\nfunction isRequired(name, fieldDesc) {\n  return fieldDesc.required || name === 'id';\n}\n\n// TODO: All of the data type needs to check the input value. This\n// doesn't just convert, it casts. See integer handling.\nexport function convertInputType(value, type) {\n  if (value === undefined) {\n    throw new Error('Query value cannot be undefined');\n  } else if (value === null) {\n    if (type === 'boolean') {\n      return 0;\n    }\n\n    return null;\n  }\n\n  switch (type) {\n    case 'date':\n      if (value instanceof Date) {\n        return toDateRepr(dayFromDate(value));\n      } else if (\n        value.match(/^\\d{4}-\\d{2}-\\d{2}$/) == null ||\n        value < '1995-01-01'\n      ) {\n        throw new Error('Invalid date: ' + value);\n      }","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/aql/schema-helpers.ts#L1-L31","documentation":"convertInputType is the value-casting entry point for AQL query parameters in Actual Budget's aql schema helpers. It deliberately rejects `undefined` values because undefined means 'no value given', which cannot be represented in the SQL layer and would silently produce broken queries if coerced. Passing undefined into a query parameter is treated as a programming error and thrown immediately.","triggerScenarios":"Calling any aql query (via paramArray/conform/value paths) with a parameter whose value is `undefined` — e.g. `{ date: someVar }` where someVar was never assigned, a missing property in an object passed to `q(...)`, or a function that forgot to return a value.","commonSituations":"Typo'd variable names, destructuring fields that don't exist on a response object, optional fields not defaulted before query execution, and JavaScript functions missing a return statement feeding into query params.","solutions":["Inspect the query parameters and find the field that is undefined at call time (log or breakpoint before building the query).","Default the value explicitly, e.g. `value ?? null` — null is accepted by convertInputType while undefined is not.","Guard before querying: skip or throw a domain-specific error when the input is missing.","Check for typos in the object property names feeding the query."],"exampleFix":"// before\nq('transactions').filter({ date: filters.startDate }); // startDate undefined\n// after\nq('transactions').filter({ date: filters.startDate ?? null });","handlingStrategy":"validation","validationCode":"function assertQueryParams(params) {\n  for (const [k, v] of Object.entries(params)) {\n    if (v === undefined) throw new Error(`Query param '${k}' is undefined`);\n  }\n}","typeGuard":"const isDefined = (v) => v !== undefined;","tryCatchPattern":"try {\n  await runQuery(buildQuery(params));\n} catch (e) {\n  if (e.message === 'Query value cannot be undefined') {\n    logger.error('Undefined query parameter', { params });\n    return null;\n  }\n  throw e;\n}","preventionTips":["Use `?? null` instead of `||` for optional query values","Enable strictNullChecks and noUncheckedIndexedAccess in TypeScript","Validate query input objects at the boundary before building aql queries"],"tags":["query","validation","undefined","aql"],"backgroundTag":"query-value-undefined","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}