cube-js/cube · error · UserError

Unsupported Python Trailer children node: ${node.constructor

Error message

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

What it means

Thrown by PythonParser.transpileToJs() when a TrailerContext (the () call or .name attribute part of an expression) has neither callArguments nor a NAME child, so the visitor cannot tell if it is a call or attribute access and throws a UserError with the context class and text.

Source

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

          const argsList = node.arglist();
          if (argsList) {
            // arglist have a single child: arguments _list_
            const args = children[0];
            return { call: args };
          } else {
            return { call: [] };
          }
        } 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) {

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Replace subscript/slice expressions (x[0]) with supported syntax — e.g. pass plain arguments to calls or restructure the model
  2. Restrict data-model Python to calls, attribute access, literals, identifiers, and lambdas
  3. Simplify the exact expression named in the error text
  4. Extend the TrailerContext branch in PythonParser.ts to handle subscripts if needed

Example fix

// before (cubes.py)
cube(config['name'], sql=config['sql'])
// after
cube('my_cube', sql='SELECT * FROM t')
Defensive patterns

Strategy: validation

Validate before calling

// Reject subscript/slice syntax before compiling
if (/\w\s*\[.*\]/.test(pySource)) {
  throw new Error('Indexing/slicing (x[...]) is not supported in data-model Python');
}

Try / catch

try {
  parsePythonAndTranspileToJs(source);
} catch (e) {
  if (e instanceof UserError && e.message.includes('Unsupported Python Trailer children')) {
    throw new Error(`Rewrite call/attribute chain: ${e.message}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: parsePythonAndTranspileToJs visits a TrailerContext whose children are neither a CallArgumentsContext (already handled) nor a NAME token — e.g. subscript trailers like obj[0], slices, or unusual parenthesis contents not captured as callArguments.

Common situations: Developers use Python indexing (items[0]), slicing, or generator expressions inside a data model file; the transpiler supports only plain calls obj(...) and attribute access obj.name, so schema compile fails.

Related errors


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