{"record":{"id":"678ab54900b27736","repo":"cube-js/cube","slug":"hierarchical-time-shift-is-not-supported-but-was-p-678ab5","errorCode":null,"errorMessage":"Hierarchical time shift is not supported but was provided for '${memPath}'. Parent time shift is '${symbol.shiftInterval}' and current is '${this.safeEvaluateSymbolContext().commonTimeShift}'","messagePattern":"Hierarchical time shift is not supported but was provided for '(.+?)'\\. Parent time shift is '(.+?)' and current is '(.+?)'","errorType":"validation","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/adapter/BaseQuery.js","lineNumber":3546,"sourceCode":"          // so we need to ignore convertTz later even if context convertTzForRawTimeDimension is set to true\n          return this.evaluateSymbolSqlWithContext(\n            () => td.dimensionSql(),\n            { ignoreConvertTzForTimeDimension: true },\n          );\n        } else {\n          let res = this.autoPrefixAndEvaluateSql(cubeName, symbol.sql, isMemberExpr);\n          const memPath = this.cubeEvaluator.pathFromArray([cubeName, name]);\n\n          // Skip view's member evaluation as there will be underlying cube's same member evaluation\n          if (symbol.type === 'time' && !this.cubeEvaluator.cubeFromPath(memPath).isView) {\n            if (this.safeEvaluateSymbolContext().timeShifts?.[memPath]) {\n              if (symbol.shiftInterval) {\n                throw new UserError(`Hierarchical time shift is not supported but was provided for '${memPath}'. Parent time shift is '${symbol.shiftInterval}' and current is '${this.safeEvaluateSymbolContext().timeShifts?.[memPath]}'`);\n              }\n              res = `(${this.addTimestampInterval(res, this.safeEvaluateSymbolContext().timeShifts?.[memPath])})`;\n            } else if (this.safeEvaluateSymbolContext().commonTimeShift) {\n              if (symbol.shiftInterval) {\n                throw new UserError(`Hierarchical time shift is not supported but was provided for '${memPath}'. Parent time shift is '${symbol.shiftInterval}' and current is '${this.safeEvaluateSymbolContext().commonTimeShift}'`);\n              }\n              res = `(${this.addTimestampInterval(res, this.safeEvaluateSymbolContext().commonTimeShift)})`;\n            }\n          }\n\n          if (this.safeEvaluateSymbolContext().convertTzForRawTimeDimension &&\n            !this.safeEvaluateSymbolContext().ignoreConvertTzForTimeDimension &&\n            !memberExpressionType &&\n            symbol.type === 'time' &&\n            this.cubeEvaluator.byPathAnyType(memberPathArray).ownedByCube\n          ) {\n            res = this.convertTz(res);\n          }\n          return res;\n        }\n      } else if (type === 'segment') {\n        if ((this.safeEvaluateSymbolContext().renderedReference || {})[memberPath]) {\n          return this.evaluateSymbolContext.renderedReference[memberPath];","sourceCodeStart":3528,"sourceCodeEnd":3564,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js#L3528-L3564","documentation":"Cube throws this when a hierarchical (rolled-up) time dimension and its parent both declare a time shift. Only one shift level is allowed along the hierarchy path, so if the parent symbol already has shiftInterval and a commonTimeShift is being applied to the child, the query is rejected at SQL evaluation time.","triggerScenarios":"A query timeDimension has timeShift on the time dimension, and the evaluated symbol (e.g. a rolled-up/hierarchical member via memPath) also defines shiftInterval, so both a per-member shift and the parent's commonTimeShift would apply.","commonSituations":"Data models that use rolled-up time dimensions from other cubes while also adding timeShift in the query or on the dimension; copying a query with timeShift onto a hierarchy-based schema; version changes where commonTimeShift handling was tightened.","solutions":["Remove timeShift from the query's timeDimension or from the symbol's shiftInterval so only one level defines a shift","Apply the shift only at the base (non-hierarchical) dimension and let the hierarchy inherit it","Use a separate dimension (pre-shifted via SQL in the schema) instead of shiftInterval on hierarchical members"],"exampleFix":"// before\ntimeDimension: { dimension: 'Orders.createdAt', dateRange: [...], timeShift: '1 month' } // where createdAt rolls up a parent with shiftInterval\n// after\ntimeDimension: { dimension: 'Orders.createdAt', dateRange: [...] } // keep shift only on the base dimension's shiftInterval","handlingStrategy":"validation","validationCode":"const q = { timeDimension: { dimension: 'Orders.createdAt', timeShift: '1 month' } };\nif (q.timeDimension?.timeShift && schemaHasShiftOnRolledUpDimension(q.timeDimension.dimension)) {\n  throw new Error('Remove either the query timeShift or the member shiftInterval: hierarchical time shift is unsupported');\n}","typeGuard":"function hasNoConflictingTimeShift(query) {\n  return !(query.timeDimension?.timeShift && query.timeDimension?.shiftInterval);\n}","tryCatchPattern":"try { await cube.query(query); } catch (e) {\n  if (/Hierarchical time shift is not supported/.test(e.message)) {\n    // strip timeShift and retry or surface a schema-design error\n  }\n  throw e;\n}","preventionTips":["Define time shifts only at the base (non-rolled-up) dimension","Never combine query-level timeShift with member-level shiftInterval in hierarchies","Add a unit test compiling any query that uses both features"],"tags":["schema-compiler","time-shift","hierarchy","sql-generation"],"backgroundTag":"hierarchical-time-shift-unsupported","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}