cube-js/cube · error · Error

Error parsing ${schemaFile.fileName}

Error message

Error parsing ${schemaFile.fileName}

What it means

During JS schema compilation the converter walks the AST looking for cube() calls and tries to extract the cube's name from the first argument. If the argument is not a string or template literal with a cooked value (e.g. an identifier, concatenation, or computed expression), the cube name cannot be determined statically and it throws.

Source

Thrown at packages/cubejs-schema-compiler/src/compiler/converters/CubeSchemaConverter.ts:127

    const ast = this.parseJS(schemaFile);

    traverse(ast, {
      CallExpression: (path) => {
        if (t.isIdentifier(path.node.callee)) {
          const args = path.get('arguments');

          if (path.node.callee.name === 'cube') {
            if (args?.[args.length - 1]) {
              let cubeName: string | undefined;

              if (args[0].node.type === 'StringLiteral' && args[0].node.value) {
                cubeName = args[0].node.value;
              } else if (args[0].node.type === 'TemplateLiteral' && args[0].node.quasis?.[0]?.value.cooked) {
                cubeName = args[0].node.quasis?.[0]?.value.cooked;
              }

              if (cubeName == null) {
                throw new Error(`Error parsing ${schemaFile.fileName}`);
              }

              if (t.isObjectExpression(args[1]?.node) && ast != null && (!filterCubeName || cubeName === filterCubeName)) {
                this.parsedFiles[cubeName] = {
                  fileName: schemaFile.fileName,
                  ast,
                  cubeDefinition: args[1].node,
                };
              }
            }
          }
        }
      },
    });
  }

  protected parseJS(file: SchemaFile) {
    try {

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Use a plain string literal as the first argument of cube(): cube('orders', {...})
  2. If using a template literal, remove all ${} interpolations so the name is fully static
  3. Compute the name in a separate variable only if you pass a literal — otherwise restructure to one cube() call per literal name

Example fix

// before
const name = 'orders';
cube(name, { sql: () => 'SELECT 1' });
// after
cube('orders', { sql: () => 'SELECT 1' });
Defensive patterns

Strategy: validation

Validate before calling

function assertStaticCubeName(callArgs) {
  const a = callArgs[0];
  if (typeof a !== 'string' || a.includes('${')) {
    throw new Error('cube() first argument must be a static string literal');
  }
}

Type guard

const isStaticCubeName = (a) => typeof a === 'string' && !a.includes('${');

Try / catch

try {
  await compiler.compile();
} catch (e) {
  if (e.message.startsWith('Error parsing ')) {
    const file = e.message.replace('Error parsing ', '');
    console.error(`cube() in ${file} uses a dynamic name — pass a string literal`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a dynamic first argument to cube() in a JS data model — a variable, string concatenation with variables, a template literal containing ${...} expressions, or cube() called with no arguments.

Common situations: Generating cube names programmatically (e.g. `cube(prefix + 'orders', ...)`); looping over configs to create cubes dynamically; refactoring that replaced a literal with a constant.

Related errors


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