actualbudget/actual · error

Parameter ${name} not provided to query

Error message

Parameter ${name} not provided to query

What it means

runCompiledAqlQuery maps the query's namedParameters (collected during compilation from `$param`-style references) to the user-supplied `params` object. If any named parameter has no corresponding entry in `params` (strictly `undefined`), a plain Error is thrown because the SQL statement cannot be safely bound.

Source

Thrown at packages/loot-core/src/server/aql/exec.ts:74

type AqlQueryParamName = string;
type AqlQueryParamValue = unknown;
export type AqlQueryParams = Record<AqlQueryParamName, AqlQueryParamValue>;

export type RunCompiledAqlQueryOptions = {
  params?: AqlQueryParams;
  executors?: Record<string, AqlQueryExecutor>;
};

export async function runCompiledAqlQuery(
  queryState: QueryState,
  sqlPieces: SqlPieces,
  compilerState: CompilerState,
  { params = {}, executors = {} }: RunCompiledAqlQueryOptions = {},
) {
  const paramArray = compilerState.namedParameters.map(param => {
    const name = param.paramName;
    if (params[name] === undefined) {
      throw new Error(`Parameter ${name} not provided to query`);
    }
    return convertInputType(params[name], param.paramType);
  });

  let data: Record<string, unknown>[] = [];
  if (executors[compilerState.implicitTableName]) {
    data = await executors[compilerState.implicitTableName](
      compilerState,
      queryState,
      sqlPieces,
      paramArray,
      compilerState.outputTypes,
    );
  } else {
    data = await execQuery(
      queryState,
      compilerState,
      sqlPieces,

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Add the missing key to the params object with the exact name the query references.
  2. Log/inspect `compilerState.namedParameters` to see which parameter names the compiled query expects.
  3. Remove the `{$param: ...}` reference from the query if the value is no longer needed, or give it a default before calling.

Example fix

// before
await aqlQuery(q('transactions').filter({date: {$gte: {$param: '$minDate'}}}), {})
// after
await aqlQuery(q('transactions').filter({date: {$gte: {$param: '$minDate'}}}), { params: { minDate: '2024-01-01' } })
Defensive patterns

Strategy: try-catch

Validate before calling

function assertParamsProvided(query, params) {
  for (const name of collectParamNames(query)) {
    if (params?.[name] === undefined) throw new Error(`Parameter ${name} not provided to query`);
  }
}

Type guard

const hasAllParams = (names, params) => names.every(n => params && params[n] !== undefined);

Try / catch

try {
  await runCompiledAqlQuery(compiled, { params });
} catch (e) {
  if (/Parameter .* not provided to query/.test(e.message)) {
    console.error('Missing query params; expected:', compiled.state.namedParameters.map(p => p.paramName));
  }
  throw e;
}

Prevention

When it happens

Trigger: Executing an AQL query containing `{$param: 'minDate'}` (or filters using `:minDate` placeholders) via `aqlQuery(q, {params: {...}})` without supplying `minDate`, or supplying it under a misspelled key.

Common situations: Renaming a parameter in the query but not in the params object, conditionally omitting a param that the query still references, or passing params through an API layer that drops undefined keys.

Related errors


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