cube-js/cube · error · Error

Can't match args for: ${func.toString()}

Error message

Can't match args for: ${func.toString()}

What it means

When CubeSymbols parses a schema function definition to extract its named arguments, it matches the function source against a FunctionRegex (arrow/function declarations with parenthesized or single params). If the source cannot be matched at all, it throws a plain Error. This typically happens with non-standard function syntax the regex cannot parse.

Source

Thrown at packages/cubejs-schema-compiler/src/compiler/CubeSymbols.ts:1315

    const oldContext = this.resolveSymbolsCallContext;
    this.resolveSymbolsCallContext = context;
    try {
      return func();
    } finally {
      this.resolveSymbolsCallContext = oldContext;
    }
  }

  public funcArguments(func: Function): string[] {
    const funcDefinition = func.toString();
    if (!this.funcArgumentsValues[funcDefinition]) {
      const match = funcDefinition.match(FunctionRegex);
      if (match && (match[1] || match[2] || match[3])) {
        this.funcArgumentsValues[funcDefinition] = (match[1] || match[2] || match[3]).split(',').map(s => s.trim());
      } else if (match) {
        this.funcArgumentsValues[funcDefinition] = [];
      } else {
        throw new Error(`Can't match args for: ${func.toString()}`);
      }
    }
    return this.funcArgumentsValues[funcDefinition];
  }

  protected joinHints(): string | string[] | undefined {
    const { joinHints } = this.resolveSymbolsCallContext || {};
    if (Array.isArray(joinHints)) {
      return R.uniq(joinHints);
    }
    return joinHints;
  }

  protected resolveSymbolsCallDeps(cubeName, sql) {
    try {
      const deps: any[] = [];
      this.resolveSymbolsCall(sql, (name) => {
        deps.push({ name });

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Ensure schema functions are plain, unbound arrow or `function` declarations written in the data model file itself.
  2. Avoid `.bind()`, curried wrappers, or imported pre-built functions where Cube needs to inspect argument names.
  3. Disable aggressive minification/transpilation for data model (schema) JS files.
  4. If using helper-generated functions, inline the SQL or arguments explicitly instead.

Example fix

// before
const totalFn = (price, tax) => `\${price} + \${tax}`;
cube('Orders', { measures: { total: { sql: totalFn.bind(null, 'price') } } });
// after
cube('Orders', { measures: { total: { sql: (price, tax) => `\${price} + \${tax}` } } });
Defensive patterns

Strategy: type-guard

Validate before calling

const src = fn.toString();
if (!/^\s*(async\s+)?(function\b|\()/i.test(src)) {
  throw new Error('Schema functions must be plain arrow/function declarations');
}

Type guard

function isPlainSchemaFn(fn) {
  const s = fn.toString();
  return !s.includes('[native code]') && /^(async\s+)?(function\b|\([^)]*\)\s*=>)/.test(s);
}

Try / catch

try { schemaCompiler.compile(); } catch (e) { if (/Can't match args for:/.test(e.message)) { console.error('Non-plain function passed to schema; inline it'); } throw e; }

Prevention

When it happens

Trigger: Passing a function whose serialized `toString()` output doesn't match common function syntax: bound functions (`Function.prototype.bind`), native/host functions, minified functions with unusual formatting, class methods extracted from compiled bundles, or functions produced by helper libraries that wrap user functions.

Common situations: Using transpiled/bundled schema code where arrow functions were rewritten to helpers; passing `myFunc.bind(null, arg)`; schemas loaded from a bundler that changes function serialization; providing a non-function or exotic callable.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/b6a7638699820f5d. Report an issue: GitHub.