actualbudget/actual · error · CompileError

Invalid field reference:

Error message

Invalid field reference: 

What it means

In compileExpr, a string expression starting with '$' is treated as a field reference: '$' alone means the implicit field, otherwise the text after '$' is the field name. If the resulting reference is null or empty (e.g. '$' with no implicit field set, or '$' followed by nothing meaningful), CompileError 'Invalid field reference: ...' is thrown.

Source

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

      literal: true,
    });
  } else if (Array.isArray(value)) {
    return typed(value, 'array', { literal: true });
  } else {
    throw new CompileError(
      'Unsupported type of expression: ' + JSON.stringify(value),
    );
  }
}

const compileExpr = saveStack('expr', (state, expr) => {
  if (typeof expr === 'string') {
    // Field reference
    if (expr[0] === '$') {
      const fieldRef = expr === '$' ? state.implicitField : expr.slice(1);

      if (fieldRef == null || fieldRef === '') {
        throw new CompileError('Invalid field reference: ' + expr);
      }

      return transformField(state, fieldRef);
    }

    // Named parameter
    if (expr[0] === ':') {
      const param = { value: '?', type: 'param', paramName: expr.slice(1) };
      state.namedParameters.push(param);
      return param;
    }
  }

  if (expr !== null) {
    if (Array.isArray(expr)) {
      return compileLiteral(expr);
    } else if (
      typeof expr === 'object' &&

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Replace '$' with a concrete field reference like '$date'
  2. Set the query's implicit field (e.g. via the appropriate query API) if you intend to use bare '$'
  3. Check dynamic field-name code for empty/undefined values before building the reference
  4. Validate field names against the schema before compiling

Example fix

// before
q.filter({ $eq: ['$', 'checking'] }) // no implicit field
// after
q.filter({ account: 'checking' }) // or use '$account'
Defensive patterns

Strategy: validation

Validate before calling

function assertFieldRef(ref, implicitField) {
  if (typeof ref === 'string' && ref.startsWith('$')) {
    const name = ref === '$' ? implicitField : ref.slice(1);
    if (!name) throw new Error(`Invalid field reference: ${ref}`);
  }
}

Type guard

function isValidFieldRef(ref, implicitField) {
  if (typeof ref !== 'string' || !ref.startsWith('$')) return true;
  const name = ref === '$' ? implicitField : ref.slice(1);
  return name != null && name !== '';
}

Try / catch

try {
  runQuery(query);
} catch (e) {
  if (/Invalid field reference/.test(e.message)) {
    console.error('Use a concrete field like $date or set the implicit field');
  }
  throw e;
}

Prevention

When it happens

Trigger: Using '$' without an implicit field configured in the query state; a string like '$' or a malformed reference that slices to an empty field name; passing '$' where a concrete field like '$date' was intended.

Common situations: Hand-written filters using bare '$' in queries where no implicit field applies; dynamic field-name construction that produced an empty string; template strings like `$${field}` where field was empty.

Related errors


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