actualbudget/actual · error · CompileError

Unknown property "${name}." Did you mean to call a function?

Error message

Unknown property "${name}." Did you mean to call a function? Try prefixing it with $

What it means

This CompileError comes from compileFunction in the AQL compiler. Function calls in AQL expressions must reference named functions with a `$` prefix (e.g. `$month`); when the key of a property in an expression object does not start with `$`, the compiler assumes it is not a function call and rejects it. The message hints that the user likely intended to call a function but forgot the `$` prefix.

Source

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

      Object.keys(expr).find(k => k[0] === '$')
    ) {
      // It's a function call
      return compileFunction(state, expr);
    }
  }

  return compileLiteral(expr);
});

const compileFunction = saveStack('function', (state, func) => {
  const [name] = Object.keys(func);
  let argExprs = func[name];
  if (!Array.isArray(argExprs)) {
    argExprs = [argExprs];
  }

  if (name[0] !== '$') {
    throw new CompileError(
      `Unknown property "${name}." Did you mean to call a function? Try prefixing it with $`,
    );
  }

  let args = argExprs;
  // `$condition` is a special-case where it will be evaluated later
  if (name !== '$condition') {
    args = argExprs.map(arg => compileExpr(state, arg));
  }

  switch (name) {
    // aggregate functions
    case '$sum': {
      validateArgLength(args, 1);
      const [arg1] = valArray(state, args, ['float']);
      return typed(`SUM(${arg1})`, args[0].type);
    }

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Prefix the function key with `$`, e.g. change `month:` to `$month:`.
  2. Check the list of supported functions in the AQL compiler to confirm the function name is valid.
  3. If you actually wanted to reference a field, use `$field` syntax on the right-hand side instead of a nested object key.

Example fix

// before
{ select: [{ date: 'day' }] }
// after
{ select: [{ day: { $date: '$date' } }] }
Defensive patterns

Strategy: validation

Validate before calling

function assertFunctionCall(expr) {
  for (const key of Object.keys(expr)) {
    if (typeof expr[key] === 'object' && expr[key] !== null && !key.startsWith('$')) {
      throw new Error(`Function "${key}" must be prefixed with $`);
    }
  }
}

Type guard

const isFunctionCall = (expr) => typeof expr === 'object' && expr !== null && Object.keys(expr).every(k => k.startsWith('$'));

Prevention

When it happens

Trigger: Calling compileQuery/`q()` with an expression object whose key is meant to be a function but lacks the `$` prefix, e.g. `{amount: {month: '$date'}}` instead of `{$month: '$date'}`.

Common situations: Hand-writing AQL expressions from memory, porting raw SQL-style field references into AQL, or copying older query examples that predate the `$`-prefixed function convention.

Related errors


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