actualbudget/actual · error · CompileError

`undefined` is not a valid query value

Error message

`undefined` is not a valid query value

What it means

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.

Source

Thrown at packages/loot-core/src/server/aql/compiler.ts:462

  )})`;

  // In production, hide internal stack traces
  if (process.env.NODE_ENV === 'production') {
    const err = new CompileError();
    err.message = `${error.message}\n\nExpression stack:` + stackStr;
    err.stack = null;
    return err;
  }

  error.message = `${error.message}\n\nExpression stack:` + stackStr;
  return error;
}

//// Compiler

function compileLiteral(value) {
  if (value === undefined) {
    throw new CompileError('`undefined` is not a valid query value');
  } else if (value === null) {
    return typed('NULL', 'null', { literal: true });
  } else if (value instanceof Date) {
    return typed(nativeDateToInt(value), 'date', { literal: true });
  } else if (typeof value === 'string') {
    // Allow user to escape $, and quote the string to make it a
    // string literal in the output
    value = value.replace(/\\\$/g, '$');
    return typed(value, 'string', { literal: true });
  } else if (typeof value === 'boolean') {
    return typed(value ? 1 : 0, 'boolean', { literal: true });
  } else if (typeof value === 'number') {
    return typed(value, Number.isInteger(value) ? 'integer' : 'float', {
      literal: true,
    });
  } else if (Array.isArray(value)) {
    return typed(value, 'array', { literal: true });
  } else {

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Replace undefined with null, omit the property, or supply the intended value
  2. Check where the value comes from — likely an unset variable, missing config key, or wrong property name
  3. Guard optional values: build the filter conditionally only when the value is defined
  4. Log/inspect the query object before compiling to spot undefined fields

Example fix

// before
q.filter({ date: startDate }) // startDate is undefined
// after
const filter = startDate != null ? { date: startDate } : {};
Defensive patterns

Strategy: validation

Validate before calling

for (const [k, v] of Object.entries(filter)) {
  if (v === undefined) throw new Error(`Query value for '${k}' is undefined`);
}

Type guard

function hasNoUndefined(obj) {
  return obj != null && Object.values(obj).every(v => v !== undefined);
}

Try / catch

try {
  runQuery(query);
} catch (e) {
  if (/`undefined` is not a valid query value/.test(e.message)) {
    console.error('Undefined query value; check variables feeding the query');
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/9c52aaefd07c4fa1. Report an issue: GitHub.