{"record":{"id":"312135c9c40ed82c","repo":"actualbudget/actual","slug":"unknown-function-name","errorCode":null,"errorMessage":"Unknown function: ${name}","messagePattern":"Unknown function: (.+?)","errorType":"exception","errorClass":"CompileError","httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/aql/compiler.ts","lineNumber":643,"sourceCode":"    case '$condition':\n      validateArgLength(args, 1);\n      const conds = compileConditions(state, args[0]);\n      return typed(conds.join(' AND '), 'boolean');\n\n    case '$nocase':\n      validateArgLength(args, 1);\n      const [arg1] = valArray(state, args, ['string']);\n      return typed(`${arg1} COLLATE NOCASE`, args[0].type);\n\n    case '$literal': {\n      validateArgLength(args, 1);\n      if (!args[0].literal) {\n        throw new CompileError('Literal not passed to $literal');\n      }\n      return args[0];\n    }\n    default:\n      throw new CompileError(`Unknown function: ${name}`);\n  }\n});\n\nconst compileOp = saveStack('op', (state, fieldRef, opData) => {\n  const { $transform, ...opExpr } = opData;\n  const [op] = Object.keys(opExpr);\n\n  const rhs = compileExpr(state, opData[op]);\n\n  let lhs;\n  if ($transform) {\n    lhs = compileFunction(\n      { ...state, implicitField: fieldRef },\n      typeof $transform === 'string' ? { [$transform]: '$' } : $transform,\n    );\n  } else {\n    lhs = compileExpr(state, '$' + fieldRef);\n  }","sourceCodeStart":625,"sourceCodeEnd":661,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/aql/compiler.ts#L625-L661","documentation":"The AQL function compiler dispatches on the function name after the `$` prefix; the `default` branch throws this CompileError when the name does not match any known function (`$literal`, `$month`, `$collate`, etc.). It means a `$`-prefixed key was found that is not a registered function.","triggerScenarios":"Calling `compileQuery`/`q()` with an expression like `{$sum: '$amount'}` where `$sum` (or any typo'd/unsupported name) is not in the compiler's function switch.","commonSituations":"Typos in function names, assuming SQL function names (SUM, COUNT) work directly in AQL, or using functions removed/renamed in a newer version of loot-core.","solutions":["Verify the function name against the supported AQL function list in compiler.ts and fix the typo.","Replace unsupported SQL aggregates with AQL equivalents (e.g. use calculated expressions or the summarize API).","If the function should exist, confirm your loot-core version supports it; upgrade if it was added later."],"exampleFix":"// before\n{$months: '$date'}\n// after\n{$month: '$date'}","handlingStrategy":"validation","validationCode":"const KNOWN_FUNCS = new Set(['$literal', '$month', '$year', '$day', '$collate', /* ...from compiler.ts */]);\nfunction assertKnownFunc(name) {\n  if (!KNOWN_FUNCS.has(name)) throw new Error(`Unknown AQL function: ${name}`);\n}","typeGuard":"const isKnownFunc = (name) => typeof name === 'string' && KNOWN_FUNCS.has(name);","tryCatchPattern":null,"preventionTips":["Keep a typed union of supported function names in application code.","Avoid assuming SQL function names exist in AQL.","Check loot-core release notes for renamed/removed functions."],"tags":["aql","query-compiler","unknown-function"],"backgroundTag":"unknown-function","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}