cube-js/cube · error · UserError

Relative-date strings are only supported when `values` has a

Error message

Relative-date strings are only supported when `values` has a single element for operator `${filter.operator}`. Pass an absolute two-element [start, end] pair, or a single relative string like ["last 2 weeks"]. Got: ${JSON.stringify(filter.values)}

What it means

Error "Relative-date strings are only supported when `values` has a single element for operator `${filter.operator}`. Pass an absolute two-element [start, end] pair, or a single relative string like ["last 2 weeks"]. Got: ${JSON.stringify(filter.values)}" thrown in cube-js/cube.

Source

Thrown at packages/cubejs-api-gateway/src/query.js:318

// with the same relative-date support that `timeDimensions.dateRange` has.
// Reuses resolveDateRange so both paths produce identical output. Non-date
// operators and already-absolute values pass through unchanged.
export const normalizeDateFilterValues = (filter, timezone) => {
  if (!filter || !filter.operator || !Array.isArray(filter.values)) {
    return filter;
  }

  // Fail fast at the gateway if a range operator is given a multi-element
  // `values` array that contains a relative-date string. This shape falls
  // through the resolver (which only handles single-element values) and
  // would otherwise error deep in query execution with an opaque message. This
  // surfaces the failure at the API boundary instead.
  if (
    (DATE_RANGE_OPERATORS.includes(filter.operator) || filter.operator === 'onTheDate') &&
    filter.values.length > 1 &&
    filter.values.some(v => typeof v === 'string' && !AbsoluteDateTimeRegex.test(v))
  ) {
    throw new UserError(
      `Relative-date strings are only supported when \`values\` has a single element for operator \`${filter.operator}\`. Pass an absolute two-element [start, end] pair, or a single relative string like ["last 2 weeks"]. Got: ${JSON.stringify(filter.values)}`
    );
  }

  if (filter.values.length !== 1) {
    return filter;
  }

  const value = filter.values[0];
  if (typeof value !== 'string') {
    return filter;
  }

  if (DATE_RANGE_OPERATORS.includes(filter.operator) || filter.operator === 'onTheDate') {
    // onTheDate resolves to a two-sided range: legacy onTheDateWhere reads
    // values[0]/values[1], and Tesseract maps onTheDate to InDateRange which
    // requires exactly 2 values.
    return { ...filter, values: resolveDateRange(value, timezone) };

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Pass an absolute two-element [start, end] date range array instead of mixing relative strings with multiple values.
  2. Collapse to a single relative-date string such as ["last 2 weeks"] so the resolver can expand it.
  3. Split into two separate filters if both a relative start and an absolute end are needed.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/cubejs-api-gateway/src/query.js:318 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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