cube-js/cube · error · UserError

MySQL can not work with table names that longer than 64 symb

Error message

MySQL can not work with table names that longer than 64 symbols. Consider using the 'sqlAlias' attribute in your cube and in your pre-aggregation definition for ${name}.

What it means

MySQL table names are limited to 64 characters. The generated pre-aggregation table name (built from cube + pre-aggregation name + suffix) exceeds that, so MysqlQuery refuses to create it and tells you to shorten it via 'sqlAlias'. This is a UserError thrown before any SQL is sent.

Source

Thrown at packages/cubejs-schema-compiler/src/adapter/MysqlQuery.ts:173

    return `SELECT TIMESTAMP(dates.f) date_from, TIMESTAMP(dates.t) date_to FROM (${values}) AS dates`;
  }

  public concatStringsSql(strings: string[]): string {
    return `CONCAT(${strings.join(', ')})`;
  }

  public unixTimestampSql(): string {
    return 'UNIX_TIMESTAMP()';
  }

  public wrapSegmentForDimensionSelect(sql: string): string {
    return `IF(${sql}, 1, 0)`;
  }

  public preAggregationTableName(cube: string, preAggregationName: string, skipSchema: boolean): string {
    const name = super.preAggregationTableName(cube, preAggregationName, skipSchema);
    if (name.length > 64) {
      throw new UserError(`MySQL can not work with table names that longer than 64 symbols. Consider using the 'sqlAlias' attribute in your cube and in your pre-aggregation definition for ${name}.`);
    }
    return name;
  }

  public supportGeneratedSeriesForCustomTd(): boolean {
    return this.useGeneratedTimeSeries;
  }

  public intervalString(interval: string): string {
    return this.formatInterval(interval);
  }

  public sqlTemplates() {
    const templates = super.sqlTemplates();
    templates.functions.STRING_AGG = 'GROUP_CONCAT({% if distinct %}DISTINCT {% endif %}{{ args[0] }} SEPARATOR {{ args[1] }})';
    templates.functions.UTCTIMESTAMP = 'UTC_TIMESTAMP()';
    // DATEADD is being rewritten to DATE_ADD, which reports sub-day intervals in
    // milliseconds. MySQL has no MILLISECOND unit, so those are scaled to microseconds

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Add sqlAlias: '<short-name>' to the pre-aggregation definition in the data model to control the table name length.
  2. Shorten the cube name or preAggregationName in the schema files.
  3. Rename the underlying table/cube hierarchy to use compact prefixes.
  4. Check the generated name in the error message and keep cube+preagg names under ~50 chars combined.

Example fix

// before
cube('marketing_attribution_daily_event_facts', { preAggregations: { main_by_user_country_and_date: {...} } })
// after
cube('marketing_attribution_daily_event_facts', { preAggregations: { main_by_user_country_and_date: { sqlAlias: 'mkt_daily', ... } } })
Defensive patterns

Strategy: validation

Validate before calling

const expectedName = `${cubeName.toLowerCase()}_${preAggName.toLowerCase()}_main`;
if (expectedName.length > 64) {
  throw new Error(`Add sqlAlias: pre-agg table name would be ${expectedName.length} chars (max 64)`);
}

Try / catch

try { await compilerApi.preAggregationsSchema(); } catch (e) { if (/MySQL can not work with table names that longer than 64/.test(e.message)) {
  console.error(`Add sqlAlias for pre-aggregation named in: ${e.message}`); } throw e; }

Prevention

When it happens

Trigger: Calling preAggregationTableName for a cube/pre-aggregation whose combined identifier exceeds 64 characters, e.g. long cube names like 'fact_table_marketing_attribution_daily_events' with a long preAggregationName like 'main_by_user_country_and_date'.

Common situations: Deeply nested cube names derived from long source tables; auto-generated pre-aggregation names from rollup joins or Cube Store workflows; schemas migrated from databases with longer identifier limits to MySQL.

Related errors


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