{"record":{"id":"1feeb64c9e9c294a","repo":"cube-js/cube","slug":"unload-is-not-configured-1feeb6","errorCode":null,"errorMessage":"Unload is not configured","messagePattern":"Unload is not configured","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cubejs-redshift-driver/src/RedshiftDriver.ts","lineNumber":422,"sourceCode":"    }\n\n    // It's possible that table is external Spectrum table, so we need to query it separately\n    const [schema, name] = table.split('.');\n\n    // We might get table from Spectrum schema, so common request via `information_schema.columns`\n    // won't return anything. `getColumnsForSpecificTables` is aware of Spectrum tables.\n    const columnRes = await this.columnsForExternalTable(schema, name);\n\n    return columnRes.map(c => ({ name: c.column_name, type: this.toGenericType(c.data_type) }));\n  }\n\n  public async isUnloadSupported() {\n    return !!this.config.exportBucket;\n  }\n\n  public async unload(tableName: string, options: UnloadOptions): Promise<DownloadTableCSVData> {\n    if (!this.config.exportBucket) {\n      throw new Error('Unload is not configured');\n    }\n\n    const types = await this.tableColumnTypes(tableName);\n    const columns = types.map(t => t.name).join(', ');\n\n    const { bucketType, bucketName, region, unloadArn, keyId, secretKey } = this.config.exportBucket;\n\n    const conn = await this.pool.acquire();\n\n    try {\n      const exportPathName = crypto.randomBytes(10).toString('hex');\n\n      const optionsToExport = {\n        REGION: `'${region}'`,\n        HEADER: '',\n        FORMAT: 'CSV',\n        GZIP: '',\n        MAXFILESIZE: `${options.maxFileSize}MB`","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-redshift-driver/src/RedshiftDriver.ts#L404-L440","documentation":"unload() implements CSV export via Redshift UNLOAD to S3, which requires the driver's exportBucket configuration. If this.config.exportBucket is undefined, the feature is not configured and the driver refuses to proceed.","triggerScenarios":"Calling unload(tableName, options) (e.g. via Cube's export feature / DownloadTableCSVData flow) on a driver instance constructed without an exportBucket config block.","commonSituations":"Calling isUnloadSupported()/unload from custom code without setting exportBucket env vars; orchestrator routes an export to a dataSource whose driver lacks exportBucket config.","solutions":["Configure exportBucket (CUBEJS_EXPORT_BUCKET_TYPE, NAME, AWS_KEY, AWS_SECRET or UNLOAD_ARN) for the Redshift driver","Check isUnloadSupported() before invoking unload and fall back to a different export path","Ensure the driver for the relevant dataSource is the Redshift driver with export config, not a misconfigured instance"],"exampleFix":"// before\nconst data = await driver.unload('pre_agg_table', options);\n// after\nif (driver.isUnloadSupported()) {\n  const data = await driver.unload('pre_agg_table', options);\n} else {\n  throw new Error('Configure exportBucket to enable Redshift unload export');\n}","handlingStrategy":"try-catch","validationCode":"if (!driver.isUnloadSupported()) {\n  throw new Error('Set exportBucket config to enable Redshift unload');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const data = await driver.unload(tableName, options);\n} catch (e) {\n  if (e.message === 'Unload is not configured') {\n    // fall back to non-UNLOAD export path\n  } else throw e;\n}","preventionTips":["Always gate unload calls on isUnloadSupported()","Configure exportBucket in every environment where CSV export is used","Centralize driver construction so export config is not missed per dataSource"],"tags":["redshift","configuration","unload","export-bucket"],"backgroundTag":"feature-not-configured","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}