{"record":{"id":"9c52aaefd07c4fa1","repo":"actualbudget/actual","slug":"undefined-is-not-a-valid-query-value","errorCode":null,"errorMessage":"`undefined` is not a valid query value","messagePattern":"`undefined` is not a valid query value","errorType":"exception","errorClass":"CompileError","httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/aql/compiler.ts","lineNumber":462,"sourceCode":"  )})`;\n\n  // In production, hide internal stack traces\n  if (process.env.NODE_ENV === 'production') {\n    const err = new CompileError();\n    err.message = `${error.message}\\n\\nExpression stack:` + stackStr;\n    err.stack = null;\n    return err;\n  }\n\n  error.message = `${error.message}\\n\\nExpression stack:` + stackStr;\n  return error;\n}\n\n//// Compiler\n\nfunction compileLiteral(value) {\n  if (value === undefined) {\n    throw new CompileError('`undefined` is not a valid query value');\n  } else if (value === null) {\n    return typed('NULL', 'null', { literal: true });\n  } else if (value instanceof Date) {\n    return typed(nativeDateToInt(value), 'date', { literal: true });\n  } else if (typeof value === 'string') {\n    // Allow user to escape $, and quote the string to make it a\n    // string literal in the output\n    value = value.replace(/\\\\\\$/g, '$');\n    return typed(value, 'string', { literal: true });\n  } else if (typeof value === 'boolean') {\n    return typed(value ? 1 : 0, 'boolean', { literal: true });\n  } else if (typeof value === 'number') {\n    return typed(value, Number.isInteger(value) ? 'integer' : 'float', {\n      literal: true,\n    });\n  } else if (Array.isArray(value)) {\n    return typed(value, 'array', { literal: true });\n  } else {","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/aql/compiler.ts#L444-L480","documentation":"compileLiteral validates literal values embedded in queries. `undefined` is explicitly rejected because it almost always signals a bug (a missing variable, an unfilled placeholder) rather than intent — null is the supported 'no value' literal. The query compiler refuses to silently emit an undefined SQL value.","triggerScenarios":"Passing an object with an undefined property value into a filter (e.g. { date: someVar } where someVar is undefined); a named-parameter object missing a key; an expression built conditionally that leaves a slot undefined.","commonSituations":"Reading config/environment values that don't exist; destructuring that missed a field; optional function args left undefined and forwarded into the query; typos in variable names.","solutions":["Replace undefined with null, omit the property, or supply the intended value","Check where the value comes from — likely an unset variable, missing config key, or wrong property name","Guard optional values: build the filter conditionally only when the value is defined","Log/inspect the query object before compiling to spot undefined fields"],"exampleFix":"// before\nq.filter({ date: startDate }) // startDate is undefined\n// after\nconst filter = startDate != null ? { date: startDate } : {};","handlingStrategy":"validation","validationCode":"for (const [k, v] of Object.entries(filter)) {\n  if (v === undefined) throw new Error(`Query value for '${k}' is undefined`);\n}","typeGuard":"function hasNoUndefined(obj) {\n  return obj != null && Object.values(obj).every(v => v !== undefined);\n}","tryCatchPattern":"try {\n  runQuery(query);\n} catch (e) {\n  if (/`undefined` is not a valid query value/.test(e.message)) {\n    console.error('Undefined query value; check variables feeding the query');\n  }\n  throw e;\n}","preventionTips":["Use null (or omit keys) instead of undefined for 'no value'","Validate variables/config feeding queries before compiling","Enable strict checks so undefined params fail early at call sites"],"tags":["aql","query-compiler","undefined","literal-validation"],"backgroundTag":"undefined-query-value","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}