{"record":{"id":"cca9479ea2709792","repo":"actualbudget/actual","slug":"this-function-cannot-track-error-data-it-needs-to","errorCode":null,"errorMessage":"This function cannot track error data. It needs to accept the compiler state as the first argument.","messagePattern":"This function cannot track error data\\. It needs to accept the compiler state as the first argument\\.","errorType":"exception","errorClass":"CompileError","httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/aql/compiler.ts","lineNumber":386,"sourceCode":"function validateArgLength(arr: unknown[], min: number, max?: number) {\n  if (max == null) {\n    max = min;\n  }\n\n  if (min != null && arr.length < min) {\n    throw new CompileError('Too few arguments');\n  }\n  if (max != null && arr.length > max) {\n    throw new CompileError('Too many arguments');\n  }\n}\n\n//// Nice errors\n\nfunction saveStack(type, func) {\n  return (state, ...args) => {\n    if (state == null || state.compileStack == null) {\n      throw new CompileError(\n        'This function cannot track error data. ' +\n          'It needs to accept the compiler state as the first argument.',\n      );\n    }\n\n    state.compileStack.push({ type, args });\n    const ret = func(state, ...args);\n    state.compileStack.pop();\n    return ret;\n  };\n}\n\nfunction prettyValue(value) {\n  if (typeof value === 'string') {\n    return value;\n  } else if (value === undefined) {\n    return 'undefined';\n  }","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/aql/compiler.ts#L368-L404","documentation":"saveStack wraps compiler functions so errors can report the failing expression via state.compileStack. If a wrapped function is invoked without a compiler state (or one lacking compileStack) as its first argument, the compiler throws this CompileError — it's an internal contract violation, usually caused by calling a compiled function directly instead of through the normal compilation path.","triggerScenarios":"Calling a wrapped compiler function (compileExpr, compileFunction, compileOp, compileWhere, compileSelect, compileGroupBy) without a state object first argument, or with state=null; custom code reusing internal compiler functions with a wrong signature.","commonSituations":"Monkey-patching or extending the compiler with custom functions that don't thread `state`; calling internal APIs in tests without constructing a state; refactors that changed the argument order.","solutions":["Always pass the compiler state as the first argument when invoking these functions","Route query compilation through the public compileQuery/aql API instead of internal functions","If adding a custom op/function, register it so the normal saveStack-wrapped path runs with a valid state","Initialize a proper state object (including compileStack) in test harnesses that call compiler internals"],"exampleFix":"// before\ncompileExpr(null, expr)\n// after\nconst state = makeCompilerState(schema); // includes compileStack: []\ncompileExpr(state, expr)","handlingStrategy":"try-catch","validationCode":"function assertCompilerState(state) {\n  if (state == null || state.compileStack == null) {\n    throw new Error('Compiler functions require a state with compileStack as first arg');\n  }\n}","typeGuard":"function hasCompilerState(args) {\n  return args.length > 0 && args[0] != null && Array.isArray(args[0].compileStack);\n}","tryCatchPattern":"try {\n  return compileExpr(state, expr);\n} catch (e) {\n  if (/cannot track error data/.test(e.message)) {\n    throw new Error('Internal misuse: pass the compiler state as first argument or use the public aql API', { cause: e });\n  }\n  throw e;\n}","preventionTips":["Don't call internal compiler functions directly; use the public aql API","Always thread `state` as the first argument in custom ops","Keep compileStack initialized when constructing test states"],"tags":["aql","query-compiler","internal-api","state"],"backgroundTag":"invalid-internal-call","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}