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
- Replace '$' with a concrete field reference like '$date'
- Set the query's implicit field (e.g. via the appropriate query API) if you intend to use bare '$'
- Check dynamic field-name code for empty/undefined values before building the reference
- 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
- Prefer explicit field references ($date) over bare '$'
- Ensure implicit field is configured whenever '$' is used
- Guard dynamically built field names against empty strings
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
- Table "${tableName}" does not exist in the schema
- Can't cast ${expr.type} to date
- Can't cast ${expr.type} to date-month
- Can't cast ${expr.type} to date-year
- Can't convert ${expr.type} to ${type}
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/14e13c8c35881a94.
Report an issue: GitHub.