{"record":{"id":"09806dca2d596cff","repo":"cube-js/cube","slug":"unable-to-detect-number-of-unloaded-records","errorCode":null,"errorMessage":"Unable to detect number of unloaded records","messagePattern":"Unable to detect number of unloaded records","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cubejs-redshift-driver/src/RedshiftDriver.ts","lineNumber":464,"sourceCode":"      await this.prepareConnection(conn, {\n        executionTimeout: this.config.executionTimeout ? this.config.executionTimeout * 1000 : 600000,\n      });\n\n      let unloadTotalRows: number | null = null;\n\n      /**\n       * @link https://github.com/brianc/node-postgres/blob/pg%408.6.0/packages/pg-protocol/src/messages.ts#L211\n       * @link https://github.com/brianc/node-postgres/blob/pg%408.6.0/packages/pg-protocol/src/parser.ts#L357\n       *\n       * message: 'UNLOAD completed, 0 record(s) unloaded successfully.',\n       */\n      conn.addListener('notice', (e: any) => {\n        if (e.message && e.message.startsWith('UNLOAD completed')) {\n          const matches = e.message.match(/\\d+/);\n          if (matches) {\n            unloadTotalRows = parseInt(matches[0], 10);\n          } else {\n            throw new Error('Unable to detect number of unloaded records');\n          }\n        }\n      });\n\n      const baseQuery = `\n        UNLOAD ('SELECT ${columns} FROM ${tableName}')\n        TO '${bucketType}://${bucketName}/${exportPathName}/'\n      `;\n\n      // Prefer the unloadArn if it is present\n      const credentialQuery = unloadArn\n        ? `iam_role '${unloadArn}'`\n        : `CREDENTIALS 'aws_access_key_id=${keyId};aws_secret_access_key=${secretKey}'`;\n\n      const unloadQuery = `${baseQuery} ${credentialQuery} ${optionsPart}`;\n\n      // Unable to extract number of extracted rows, because it's done in protocol notice\n      await conn.query({","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-redshift-driver/src/RedshiftDriver.ts#L446-L482","documentation":"After running UNLOAD, the driver parses the 'UNLOAD completed, N records unloaded' notice from the connection to learn how many rows were exported. If the notice text matches the prefix but contains no digits, the driver throws because it cannot determine the unloaded record count.","triggerScenarios":"A 'notice' listener on the pg connection receives a message starting with 'UNLOAD completed' whose text yields no /\\d+/ match — e.g. a truncated or non-standard notice message from a proxy or newer Redshift/psg client formatting.","commonSituations":"Intermediate network layers (pgbouncer-like proxies, custom pg wrappers) rewriting notices; unusual Redshift-compatible engines returning differently worded messages.","solutions":["Inspect the notice message logged by the connection and confirm the driver/Node pg version renders Redshift notices intact","Connect directly to Redshift (bypass proxies) so the standard 'UNLOAD completed, N records' notice arrives","Upgrade cubejs-redshift-driver / pg client, then retry the export"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await driver.unload(tableName, options);\n} catch (e) {\n  if (e.message.startsWith('Unable to detect number of unloaded records')) {\n    // verify S3 listing separately or retry; log the raw notice for diagnosis\n  }\n  throw e;\n}","preventionTips":["Avoid proxies/middleware between Cube and Redshift that rewrite pg notices","Keep pg client and driver versions current","Log connection notices in dev to verify UNLOAD messages arrive intact"],"tags":["redshift","unload","notice-parsing"],"backgroundTag":"unload-notice-parse-failed","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}