{"record":{"id":"42247e1ae6a33b01","repo":"cube-js/cube","slug":"unsupported-python-multiple-children-node-node","errorCode":null,"errorMessage":"Unsupported Python multiple children node: ${node.constructor.name}: ${node.getText()}","messagePattern":"Unsupported Python multiple children node: (.+?): (.+?)","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/parser/PythonParser.ts","lineNumber":136,"sourceCode":"\n    const parser = new Python3Parser(\n      commonTokenStream\n    );\n    parser.buildParseTrees = true;\n    parser.removeErrorListeners();\n    parser.addErrorListener(new ExprErrorListener());\n\n    return parser.file_input();\n  }\n\n  public transpileToJs(): t.Program {\n    return this.ast.accept(nodeVisitor<any>({\n      visitNode: (node, children) => {\n        const singleNodeReturn = () => {\n          if (children.length === 1) {\n            return children[0];\n          } else {\n            throw new UserError(`Unsupported Python multiple children node: ${node.constructor.name}: ${node.getText()}`);\n          }\n        };\n\n        if (node instanceof File_inputContext) {\n          return t.program(children);\n        } else if (node instanceof Expr_stmtContext) {\n          if (children.length === 1) {\n            return t.expressionStatement(children[0]);\n          } else {\n            throw new UserError(`Unsupported Python multiple children node: ${node.constructor.name}: ${node.getText()}`);\n          }\n        } else if (\n          node instanceof Double_string_template_atomContext ||\n          node instanceof Single_string_template_atomContext\n        ) {\n          if ((node.test() || node.star_expr()) && children.length === 1) {\n            return children[0];\n          }","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/parser/PythonParser.ts#L118-L154","documentation":"This UserError is thrown by PythonParser.transpileToJs() during Python-to-JavaScript transpilation of a Cube data model. The visitor's singleNodeReturn() helper expects a parse-tree node to reduce to exactly one child; when an AST node (typically an AtomContext with unsupported content like a parenthesized expression or list) produces zero or multiple children, the transpiler refuses to guess a mapping and throws, naming the ANTLR context class and source text.","triggerScenarios":"Calling parsePythonAndTranspileToJs (via transpileToJs) on Python data-model code where a node visited via singleNodeReturn() — e.g. an AtomContext not matching NAME/STRING/NUMBER — yields a children array whose length is not 1. Typical sources: Python syntax beyond the supported subset such as tuples, lists, dict literals, parenthesized expressions, or multiple statements in one expr line.","commonSituations":"Developers writing advanced Python in cubes.py (list/tuple/dict literals, f-strings with complex expressions, arithmetic in attribute defaults, decorators, imports) assume full Python support, but the Cube Python transpiler only supports a small expression subset; CI fails during schema compile with this message.","solutions":["Rewrite the Python model to use only the supported subset: plain literals, identifiers, simple function calls, attribute access, and lambdas","Replace container literals (tuples/lists/dicts) with multiple assignments or simple single expressions","Check the node class name and text in the message to find the offending line, and simplify that exact expression","If a supported construct is being rejected, inspect packages/cubejs-schema-compiler/src/parser/PythonParser.ts visitNode branches and file an issue / add a mapping for the missing context"],"exampleFix":"// before (cubes.py)\ndims = ['a', 'b']\ncube(name=dims[0])\n// after\nname = 'a'\ncube(name=name)","handlingStrategy":"validation","validationCode":"// Keep model Python within the supported subset before compiling\nconst SUPPORTED = /^[\\w\\s.'\"(),:=*+\\-]+$/;\nif (!SUPPORTED.test(pySource)) throw new Error('Model uses constructs outside the supported Python subset');\nif (/[[\\]{}]|await |yield /.test(pySource)) throw new Error('Lists/dicts/await are not supported in data models');","typeGuard":null,"tryCatchPattern":"try {\n  compiler.compileJsFile(...); // parsePythonAndTranspileToJs\n} catch (e) {\n  if (e instanceof UserError && e.message.startsWith('Unsupported Python multiple children node')) {\n    throw new Error(`Simplify this model expression: ${e.message}`);\n  }\n  throw e;\n}","preventionTips":["Use only literals, identifiers, calls, attribute access and lambdas in data-model Python","Avoid container literals (lists, tuples, dicts) and slicing/indexing in cubes.py","Validate model files with python -m py_compile before starting Cube","Read the node class + text in the message to pinpoint the offending expression quickly"],"tags":["python","transpilation","schema-compiler","unsupported-syntax"],"backgroundTag":"python-transpile-unsupported-node","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}