cube-js/cube · error · UserError

Hierarchical time shift is not supported but was provided fo

Error message

Hierarchical time shift is not supported but was provided for '${memPath}'. Parent time shift is '${symbol.shiftInterval}' and current is '${this.safeEvaluateSymbolContext().commonTimeShift}'

What it means

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.

Source

Thrown at packages/cubejs-schema-compiler/src/adapter/BaseQuery.js:3546

          // so we need to ignore convertTz later even if context convertTzForRawTimeDimension is set to true
          return this.evaluateSymbolSqlWithContext(
            () => td.dimensionSql(),
            { ignoreConvertTzForTimeDimension: true },
          );
        } else {
          let res = this.autoPrefixAndEvaluateSql(cubeName, symbol.sql, isMemberExpr);
          const memPath = this.cubeEvaluator.pathFromArray([cubeName, name]);

          // Skip view's member evaluation as there will be underlying cube's same member evaluation
          if (symbol.type === 'time' && !this.cubeEvaluator.cubeFromPath(memPath).isView) {
            if (this.safeEvaluateSymbolContext().timeShifts?.[memPath]) {
              if (symbol.shiftInterval) {
                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]}'`);
              }
              res = `(${this.addTimestampInterval(res, this.safeEvaluateSymbolContext().timeShifts?.[memPath])})`;
            } else if (this.safeEvaluateSymbolContext().commonTimeShift) {
              if (symbol.shiftInterval) {
                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}'`);
              }
              res = `(${this.addTimestampInterval(res, this.safeEvaluateSymbolContext().commonTimeShift)})`;
            }
          }

          if (this.safeEvaluateSymbolContext().convertTzForRawTimeDimension &&
            !this.safeEvaluateSymbolContext().ignoreConvertTzForTimeDimension &&
            !memberExpressionType &&
            symbol.type === 'time' &&
            this.cubeEvaluator.byPathAnyType(memberPathArray).ownedByCube
          ) {
            res = this.convertTz(res);
          }
          return res;
        }
      } else if (type === 'segment') {
        if ((this.safeEvaluateSymbolContext().renderedReference || {})[memberPath]) {
          return this.evaluateSymbolContext.renderedReference[memberPath];

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Remove timeShift from the query's timeDimension or from the symbol's shiftInterval so only one level defines a shift
  2. Apply the shift only at the base (non-hierarchical) dimension and let the hierarchy inherit it
  3. Use a separate dimension (pre-shifted via SQL in the schema) instead of shiftInterval on hierarchical members

Example fix

// before
timeDimension: { dimension: 'Orders.createdAt', dateRange: [...], timeShift: '1 month' } // where createdAt rolls up a parent with shiftInterval
// after
timeDimension: { dimension: 'Orders.createdAt', dateRange: [...] } // keep shift only on the base dimension's shiftInterval
Defensive patterns

Strategy: validation

Validate before calling

const q = { timeDimension: { dimension: 'Orders.createdAt', timeShift: '1 month' } };
if (q.timeDimension?.timeShift && schemaHasShiftOnRolledUpDimension(q.timeDimension.dimension)) {
  throw new Error('Remove either the query timeShift or the member shiftInterval: hierarchical time shift is unsupported');
}

Type guard

function hasNoConflictingTimeShift(query) {
  return !(query.timeDimension?.timeShift && query.timeDimension?.shiftInterval);
}

Try / catch

try { await cube.query(query); } catch (e) {
  if (/Hierarchical time shift is not supported/.test(e.message)) {
    // strip timeShift and retry or surface a schema-design error
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/678ab54900b27736. Report an issue: GitHub.