{"record":{"id":"389a41078c3c1c24","repo":"cube-js/cube","slug":"last-argument-should-be-a-function","errorCode":null,"errorMessage":"Last argument should be a function","messagePattern":"Last argument should be a function","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/extensions/Reflection.ts","lineNumber":15,"sourceCode":"import R from 'ramda';\nimport { DynamicReference } from '../compiler/DynamicReference';\nimport { AbstractExtension } from './extension.abstract';\n\nexport class Reflection extends AbstractExtension {\n  public dynRef = (...args) => {\n    if (args.length < 2) {\n      throw new Error('List of references and a function are expected in form: dynRef(\\'ref\\', (r) => (...))');\n    }\n\n    const references = R.dropLast(1, args);\n    const fn = args[args.length - 1];\n\n    if (typeof fn !== 'function') {\n      throw new Error('Last argument should be a function');\n    }\n\n    return new DynamicReference(references, fn);\n  };\n}\n","sourceCodeStart":1,"sourceCodeEnd":21,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/extensions/Reflection.ts#L1-L21","documentation":"dynRef treats its last argument as the function that computes the reference SQL and everything before it as reference names. If the final argument is not a function it throws, since the reference cannot be evaluated.","triggerScenarios":"Calling dynRef('ref', 'notAFunction'), dynRef('ref', someObject), or building args where the callback is missing or in the wrong position.","commonSituations":"Passing a string of SQL instead of a function; forgetting the arrow function; accidentally reordering arguments so a string lands last; a variable expected to be a function being undefined due to an import error.","solutions":["Ensure the last argument is a function: dynRef('ref', (r) => `...` )","If references and the function are in an array, keep the function as the final element","Log/console-check the arguments being spread into dynRef when constructing them dynamically"],"exampleFix":"// before\ndynRef('users', 'count(*)');\n// after\ndynRef('users', (r) => `count(*)`);","handlingStrategy":"validation","validationCode":"const lastIsFn = (...args) => typeof args[args.length - 1] === 'function';","typeGuard":"const lastIsFn = (...args) => typeof args[args.length - 1] === 'function';","tryCatchPattern":"try {\n  const ref = reflection.dynRef(...dynRefArgs);\n} catch (e) {\n  if (e.message === 'Last argument should be a function') {\n    console.error('dynRef requires its final argument to be a callback function');\n  }\n  throw e;\n}","preventionTips":["Always end dynRef calls with an arrow function","Check argument order when constructing dynRef args dynamically","Type dynamic ref builders in TypeScript: (...refs: string[], fn: (r: any) => string) => DynamicReference"],"tags":["dynamic-reference","extension","argument-validation"],"backgroundTag":"invalid-argument","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}