cube-js/cube · error

Unable to import (as csv) in Cube Store: empty columns. Most

Error message

Unable to import (as csv) in Cube Store: empty columns. Most probably, introspection has failed.

What it means

Same root cause as the rows variant, but for CSV-file based imports: importCsvFile needs column definitions to emit the CREATE TABLE SQL before loading the CSV. An empty columns array indicates failed introspection.

Source

Thrown at packages/cubejs-cubestore-driver/src/CubeStoreDriver.ts:326

          .reduce((a, b) => a.concat(b), []);

        await this.query(
          `INSERT INTO ${table}
        (${columns.map(c => this.quoteIdentifier(c.name)).join(', ')})
        VALUES ${valueParamPlaceholders}`,
          params,
          queryTracingObj
        );
      }
    } catch (e) {
      await this.dropTable(table);
      throw e;
    }
  }

  private async importCsvFile(tableData: DownloadTableCSVData, table: string, columns: Column[], indexes: any, aggregations: any, queryTracingObj?: any) {
    if (!columns || columns.length === 0) {
      throw new Error('Unable to import (as csv) in Cube Store: empty columns. Most probably, introspection has failed.');
    }

    const files = Array.isArray(tableData.csvFile) ? tableData.csvFile : [tableData.csvFile];
    const options: CreateTableOptions = {
      buildRangeEnd: queryTracingObj?.buildRangeEnd,
      indexes,
      aggregations
    };
    if (files.length > 0) {
      options.inputFormat = tableData.csvNoHeader ? 'csv_no_header' : 'csv';
      if (tableData.csvDelimiter) {
        options.delimiter = tableData.csvDelimiter;
      }
      if (tableData.csvDisableQuoting) {
        options.disableQuoting = tableData.csvDisableQuoting;
      }
      options.files = files;
    }

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Fix or re-run introspection so columns are derived from the CSV schema.
  2. Supply columns explicitly when calling uploadTable if introspection is unreliable.
  3. Verify the CSV source driver is supported and returns metadata.
  4. Update cubejs-schema-compiler and driver packages to compatible versions.

Example fix

// before
await driver.uploadTable(table, [], { csvFile: 'data.csv' });
// after
const columns = [{ name: 'id', type: 'text' }, { name: 'ts', type: 'timestamp' }];
await driver.uploadTable(table, columns, { csvFile: 'data.csv' });
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(columns) || columns.length === 0) {
  throw new Error('Refusing CSV import: no columns from introspection');
}
await driver.uploadTable(table, columns, { csvFile });

Type guard

function hasColumns(c: unknown): c is Array<{ name: string; type: string }> {
  return Array.isArray(c) && c.length > 0 && c.every(col => typeof (col as any).name === 'string');
}

Try / catch

try {
  await driver.uploadTable(table, columns, { csvFile });
} catch (e) {
  if (e.message.includes('as csv') && e.message.includes('empty columns')) {
    console.error('CSV introspection failed: provide explicit columns or fix the CSV source driver');
  }
  throw e;
}

Prevention

When it happens

Trigger: uploadTable with tableData.csvFile but columns empty/null — introspection for the CSV source returned no columns.

Common situations: CSV data source with headers the introspection stage can't parse; driver bug returning empty metadata; schema whose pre-aggregation columns resolve to zero.

Related errors


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