{"record":{"id":"aecca313c26202d4","repo":"cube-js/cube","slug":"comparedaterange-can-only-exist-for-one-timedimens","errorCode":null,"errorMessage":"compareDateRange can only exist for one timeDimension","messagePattern":"compareDateRange can only exist for one timeDimension","errorType":"validation","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-api-gateway/src/gateway.ts","lineNumber":2937,"sourceCode":"        type: 'Outgoing network usage',\n        service: 'api-http',\n        bytes: Number(res.get('content-length')) || 0,\n        path: req.path,\n      }, req.context);\n    });\n    if (next) {\n      next();\n    }\n  };\n\n  protected compareDateRangeTransformer(query) {\n    let queryCompareDateRange;\n    let compareDateRangeTDIndex;\n\n    (query.timeDimensions || []).forEach((td, index) => {\n      if (td.compareDateRange != null) {\n        if (queryCompareDateRange != null) {\n          throw new UserError('compareDateRange can only exist for one timeDimension');\n        }\n\n        queryCompareDateRange = td.compareDateRange;\n        compareDateRangeTDIndex = index;\n      }\n    });\n\n    if (queryCompareDateRange == null) {\n      return query;\n    }\n\n    return queryCompareDateRange.map((dateRange) => ({\n      ...R.clone(query),\n      timeDimensions: query.timeDimensions.map((td, index) => {\n        if (compareDateRangeTDIndex === index) {\n          // eslint-disable-next-line @typescript-eslint/no-unused-vars\n          const { compareDateRange, ...timeDimension } = td;\n          return {","sourceCodeStart":2919,"sourceCodeEnd":2955,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-api-gateway/src/gateway.ts#L2919-L2955","documentation":"The `compareDateRange` option is a convenience that expands one query into multiple date-range variants, so it may be set on at most one timeDimension. Before converting the query, the gateway scans query.timeDimensions and throws this UserError if more than one timeDimension has a non-null compareDateRange.","triggerScenarios":"Submitting a /cubejs-api/v1/load query whose timeDimensions array contains two or more entries each with `compareDateRange` set — e.g. comparing two different date ranges for two different dimensions in one request.","commonSituations":"Programmatic query builders accumulating compareDateRange across dimensions; UI clients letting users pick a comparison range per dimension; hand-editing a JSON query copied from another example.","solutions":["Keep compareDateRange on only one timeDimension; remove it from the others.","If you need comparisons across multiple dimensions, split into separate API requests and merge results client-side.","Use explicit dateRange arrays per timeDimension plus separate queries instead of the compareDateRange shortcut when comparing multiple dimensions."],"exampleFix":"// before\ntimeDimensions: [\n  { dimension: 'Events.date', compareDateRange: ['2024-01-01','2024-01-31'] },\n  { dimension: 'Users.created', compareDateRange: ['2023-01-01','2023-01-31'] }\n]\n// after\ntimeDimensions: [\n  { dimension: 'Events.date', compareDateRange: ['2024-01-01','2024-01-31'] },\n  { dimension: 'Users.created', dateRange: ['2023-01-01','2023-01-31'] }\n]","handlingStrategy":"validation","validationCode":"function validateCompareDateRange(query) {\n  const count = (query.timeDimensions || []).filter(td => td.compareDateRange != null).length;\n  if (count > 1) throw new Error('compareDateRange allowed on at most one timeDimension');\n}","typeGuard":"function hasAtMostOneCompareDateRange(query) {\n  return (query.timeDimensions || []).filter(td => td.compareDateRange != null).length <= 1;\n}","tryCatchPattern":"try {\n  await cubeApi.load(query);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('compareDateRange')) {\n    // strip compareDateRange from all but one timeDimension and retry\n  }\n  throw e;\n}","preventionTips":["Normalize queries in your query-builder layer before sending: keep compareDateRange on one dimension only","Constrain the UI so the comparison picker applies to a single timeDimension","Add a JSON-schema or zod validation for outgoing queries"],"tags":["query","validation","time-dimensions","user-error"],"backgroundTag":"invalid-query-time-dimensions","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}