{"record":{"id":"f45e013dfcb09629","repo":"cube-js/cube","slug":"can-t-build-query-for-time-dimensions-with-differe","errorCode":null,"errorMessage":"Can't build query for time dimensions with different date ranges","messagePattern":"Can't build query for time dimensions with different date ranges","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/adapter/BaseQuery.js","lineNumber":2005,"sourceCode":"          // filter condition again and again. Different granularities don't play role here,\n          // as rollingWindow.granularity is used for filtering.\n          uniqDateJoinCondition,\n          fromRollup,\n          false\n        ));\n      return baseQueryFn(cumulativeMeasures, filters, false);\n    }\n\n    if (this.timeDimensions.filter(d => !d.dateRange && d.granularity).length > 0) {\n      throw new UserError('Time series queries without dateRange aren\\'t supported');\n    }\n\n    // We can't do meaningful query if few time dimensions with different ranges passed,\n    // it won't be possible to join them together without losing some rows.\n    const rangedTimeDimensions = this.timeDimensions.filter(d => d.dateRange && d.granularity);\n    const uniqTimeDimensionWithRanges = R.uniqBy(d => d.dateRange, rangedTimeDimensions);\n    if (uniqTimeDimensionWithRanges.length > 1) {\n      throw new Error('Can\\'t build query for time dimensions with different date ranges');\n    }\n\n    // We need to generate time series table for the lowest granularity among all time dimensions\n    const [dateSeriesDimension, dateSeriesGranularity] = this.timeDimensions.filter(d => d.granularity)\n      .reduce(([prevDim, prevGran], d) => {\n        const mg = this.minGranularity(prevGran, d.resolvedGranularity());\n        if (mg === d.resolvedGranularity()) {\n          return [d, mg];\n        }\n        return [prevDim, mg];\n      }, [null, null]);\n\n    const dateSeriesSql = this.dateSeriesSql(dateSeriesDimension);\n\n    // If the same time dimension is passed more than once, no need to build the same\n    // filter condition again and again. Different granularities don't play role here,\n    // as rollingWindow.granularity is used for filtering.\n    const filters = this.segments","sourceCodeStart":1987,"sourceCodeEnd":2023,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js#L1987-L2023","documentation":"When multiple time dimensions with granularities and date ranges are present, Cube must generate one shared time series; if the unique date ranges differ, rows would be lost when joining. Cube therefore refuses and throws this Error.","triggerScenarios":"A single query with two or more timeDimensions (each with granularity) whose dateRange values are not identical — R.uniqBy(d => d.dateRange) yields more than one entry.","commonSituations":"Comparing two events on different windows (e.g. signup range Jan–Mar, purchase range Feb–Apr) in one query; dashboard widgets merging multiple time dimensions with independently chosen ranges.","solutions":["Make all granular time dimensions in the query use the exact same dateRange.","Split into separate queries (one per time dimension range) and merge results in application code.","Remove granularity from the extra time dimensions (turn them into plain range filters) so only one ranged/granular dimension remains.","Wrap query construction and return a user-facing message asking to unify the date range."],"exampleFix":"// before\ntimeDimensions: [\n  { dimension: 'Signups.time', granularity: 'day', dateRange: ['2024-01-01','2024-03-01'] },\n  { dimension: 'Purchases.time', granularity: 'day', dateRange: ['2024-02-01','2024-04-01'] }\n]\n// after\ntimeDimensions: [\n  { dimension: 'Signups.time', granularity: 'day', dateRange: ['2024-01-01','2024-03-01'] },\n  { dimension: 'Purchases.time', granularity: 'day', dateRange: ['2024-01-01','2024-03-01'] }\n]","handlingStrategy":"validation","validationCode":"function requireSameDateRanges(query) {\n  const ranges = (query.timeDimensions || [])\n    .filter(td => td.granularity && td.dateRange)\n    .map(td => JSON.stringify(td.dateRange));\n  if (new Set(ranges).size > 1) {\n    throw new Error('All granular timeDimensions must share the same dateRange');\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await cubeApi.load(query);\n} catch (e) {\n  if (/different date ranges/.test(e.message)) {\n    console.error('Unify time dimension ranges or split the query');\n  }\n  throw e;\n}","preventionTips":["Normalize all timeDimensions to one canonical range in your query builder","Split multi-range comparisons into separate queries","Keep only one ranged+granular time dimension per query when possible"],"tags":["time-dimensions","date-range","query-validation"],"backgroundTag":"inconsistent-time-dimension-ranges","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}