actualbudget/actual · error

Query value cannot be undefined

Error message

Query value cannot be undefined

What it means

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.

Source

Thrown at packages/loot-core/src/server/aql/schema-helpers.ts:13

import { fromDateRepr, toDateRepr } from '#server/models';
// @ts-strict-ignore
import { dayFromDate } from '#shared/months';

function isRequired(name, fieldDesc) {
  return fieldDesc.required || name === 'id';
}

// TODO: All of the data type needs to check the input value. This
// doesn't just convert, it casts. See integer handling.
export function convertInputType(value, type) {
  if (value === undefined) {
    throw new Error('Query value cannot be undefined');
  } else if (value === null) {
    if (type === 'boolean') {
      return 0;
    }

    return null;
  }

  switch (type) {
    case 'date':
      if (value instanceof Date) {
        return toDateRepr(dayFromDate(value));
      } else if (
        value.match(/^\d{4}-\d{2}-\d{2}$/) == null ||
        value < '1995-01-01'
      ) {
        throw new Error('Invalid date: ' + value);
      }

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Inspect the query parameters and find the field that is undefined at call time (log or breakpoint before building the query).
  2. Default the value explicitly, e.g. `value ?? null` — null is accepted by convertInputType while undefined is not.
  3. Guard before querying: skip or throw a domain-specific error when the input is missing.
  4. Check for typos in the object property names feeding the query.

Example fix

// before
q('transactions').filter({ date: filters.startDate }); // startDate undefined
// after
q('transactions').filter({ date: filters.startDate ?? null });
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

const isDefined = (v) => v !== undefined;

Try / catch

try {
  await runQuery(buildQuery(params));
} catch (e) {
  if (e.message === 'Query value cannot be undefined') {
    logger.error('Undefined query parameter', { params });
    return null;
  }
  throw e;
}

Prevention

When it happens

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

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

Related errors


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