cube-js/cube · error · UserError

Unsupported Python vfpdef children node: ${node.constructor.

Error message

Unsupported Python vfpdef children node: ${node.constructor.name}: ${node.getText()}

What it means

Thrown by PythonParser.transpileToJs() when a VfpdefContext (a function-parameter definition inside a lambda/def parameter list) has no NAME token, so no identifier can be created for the parameter. The visitor throws a UserError naming the context and its text.

Source

Thrown at packages/cubejs-schema-compiler/src/parser/PythonParser.ts:226

          }
        } else if (node instanceof TrailerContext) {
          const name = node.NAME();
          const argsList = node.callArguments();
          if (argsList) {
            // trailer with callArguments have a single child: CallArgumentsContext
            // which was already processed (see other if branch)
            return children[0];
          } else if (name) {
            return { identifier: t.identifier(name.getText()) };
          } else {
            throw new UserError(`Unsupported Python Trailer children node: ${node.constructor.name}: ${node.getText()}`);
          }
        } else if (node instanceof VfpdefContext) {
          const name = node.NAME();
          if (name) {
            return t.identifier(name.getText());
          } else {
            throw new UserError(`Unsupported Python vfpdef children node: ${node.constructor.name}: ${node.getText()}`);
          }
        } else if (node instanceof VarargslistContext) {
          return { args: children };
        } else if (node instanceof LambdefContext) {
          return t.arrowFunctionExpression(children[0].args, children[1]);
        } else if (node instanceof Not_testContext) {
          if (node.getChildCount() === 1) {
            return children[0];
          }
          return t.unaryExpression('!', children[0]);
        } else if (node instanceof And_testContext) {
          if (children.length === 1) {
            return children[0];
          }
          return children.reduce((left, right) => t.logicalExpression('&&', left, right));
        } else if (node instanceof Or_testContext) {
          if (children.length === 1) {
            return children[0];

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Fix syntax errors in lambda/function parameter lists in the data model file (run the file through Python to validate first)
  2. Rewrite parameter definitions as plain identifiers without type annotations
  3. Simplify the lambda to a single plain parameter, e.g. lambda x: ...
  4. Report as a bug if valid Python triggers it, including the snippet from the error text

Example fix

// before (cubes.py)
convert = lambda x: x.upper  # malformed/empty param from typo: lambda : .upper
// after
convert = lambda x: x.upper()
Defensive patterns

Strategy: validation

Validate before calling

// Validate lambdas/params with real Python first
const { execSync } = require('child_process');
try { execSync(`python3 -c "compile(open('model.py').read(),'model.py','exec')"`); }
catch { throw new Error('Model file has Python syntax errors (check lambda parameter lists)'); }

Try / catch

try {
  parsePythonAndTranspileToJs(source);
} catch (e) {
  if (e instanceof UserError && e.message.includes('Unsupported Python vfpdef')) {
    throw new Error(`Malformed lambda parameter: ${e.message}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: parsePythonAndTranspileToJs visits a VfpdefContext where node.NAME() is null — typically from ANTLR error recovery on malformed parameter lists, or parameter forms (typed/starred params) not represented as a plain NAME in the grammar path taken.

Common situations: Usually follows a syntax error in a lambda or function definition in the data model (e.g. lambda with malformed arguments) where recovery produced an empty vfpdef node; rarely hit by valid Python.

Related errors


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