cube-js/cube · error
Query must be defined in options
Error message
Query must be defined in options
What it means
A validation guard in ClickHouseDriver.unload: unloading a table in the ClickHouse driver is implemented by running a caller-supplied SELECT (`options.query.sql`) and inserting its results, since ClickHouse has no native server-side unload API. Throwing when options.query is missing means unloadWithoutTempTable strategy was requested without defining the source query; callers must pass a query in UnloadOptions.
Source
Thrown at packages/cubejs-clickhouse-driver/src/ClickHouseDriver.ts:608
await this.command(query);
}
public override async createTable(quotedTableName: string, columns: TableColumn[]) {
const createTableSql = this.createTableSql(quotedTableName, columns);
try {
await this.command(createTableSql);
} catch (e) {
// TODO replace string formatting with proper cause
throw new Error(`Create table failed: ${e}`);
}
}
/**
* We use unloadWithoutTempTable strategy
*/
public async unload(_tableName: string, options: UnloadOptions): Promise<DownloadTableCSVData> {
if (!options.query?.sql) {
throw new Error('Query must be defined in options');
}
return this.unloadFromQuery(
options.query?.sql,
options.query?.params,
options
);
}
public async unloadFromQuery(sql: string, params: unknown[], _options: UnloadOptions): Promise<DownloadTableCSVData> {
if (!this.config.exportBucket) {
throw new Error('Unload is not configured');
}
const types = await this.queryColumnTypes(`(${sql})`, params);
const { bucketName, path } = this.parseBucketUrl(this.config.exportBucket.bucketName);
const exportPrefix = path ? `${path}/${uuidv4()}` : uuidv4();
View on GitHub (pinned to 7d981676b3)
Solutions
- Ensure the caller passes options.query = { sql, params } when invoking unload()
- Verify the pre-aggregation unload strategy configuration so Cube's orchestrator populates UnloadOptions.query
- If calling manually, use unloadFromQuery(sql, params, options) instead when you have raw SQL
- Add a guard in calling code to fail fast with a clear message before invoking unload()
Example fix
// before
await driver.unload('my_preagg', {} as UnloadOptions);
// after
await driver.unload('my_preagg', { query: { sql: 'SELECT ...', params: [] } } as UnloadOptions); Defensive patterns
Strategy: validation
Validate before calling
const canUnload = (options?: UnloadOptions): options is UnloadOptions & { query: { sql: string; params: unknown[] } } =>
Boolean(options?.query?.sql); Type guard
const hasUnloadQuery = (o: UnloadOptions): o is UnloadOptions & { query: { sql: string; params: unknown[] } } =>
typeof o?.query?.sql === 'string' && o.query.sql.length > 0; Try / catch
try { return await driver.unload(table, options); }
catch (e) {
if (String(e.message) === 'Query must be defined in options') throw new Error('UnloadOptions.query.sql is required for unload', { cause: e });
throw e;
} Prevention
- Always populate UnloadOptions.query with { sql, params }
- Prefer unloadFromQuery() when calling manually with raw SQL
- Fail fast in calling code before invoking unload()
When it happens
Trigger: Calling driver.unload(tableName, options) with options lacking a query object, or with query defined but sql undefined/empty — typically from an orchestrator/pre-aggregation path that did not populate UnloadOptions.query.
Common situations: Custom code calling unload() directly with only a table name; drivers/configurations where the unload strategy (unloadWithoutTempTable) is set but the caller builds UnloadOptions without query; null propagation from upstream query builders.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- Unload is not configured
- Export bucket is not configured.
- Unload is not configured
- Unsupported EXPORT_BUCKET_TYPE, supported: ${SUPPORTED_BUCKE
- Unsupported configuration exportBucket, some configuration k
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/2d4ecc8c0eeba899.
Report an issue: GitHub.