cube-js/cube · error · UserError

Incorrect timezone ${this.timezone}

Error message

Incorrect timezone ${this.timezone}

What it means

BaseQuery canonicalizes the query's timezone through canonicalTimezone() so every SQL dialect's convertTz() receives a valid zone. If the provided timezone string cannot be canonicalized (unknown or invalid IANA name/offset), the query is rejected with this UserError.

Source

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

      localRefreshKey: this.options.localRefreshKey,
      from: this.options.from,
      multiStageQuery: this.options.multiStageQuery,
      multiStageDimensions: this.options.multiStageDimensions,
      multiStageTimeDimensions: this.options.multiStageTimeDimensions,
      subqueryJoins: this.options.subqueryJoins,
      joinHints: this.options.joinHints,
      maskedMembers: this.options.maskedMembers,
    });
    this.from = this.options.from;
    this.multiStageQuery = this.options.multiStageQuery;
    this.timezone = this.options.timezone;

    // Backstop for every dialect convertTz() sink: callers that bypass the API gateway
    // (queryRewrite, refresh scheduler, SQL API sessions) reach the dialects through here.
    if (this.timezone) {
      const timezone = canonicalTimezone(this.timezone);
      if (!timezone) {
        throw new UserError(`Incorrect timezone ${this.timezone}`);
      }

      this.timezone = timezone;
    }

    this.rowLimit = this.options.rowLimit;
    this.offset = this.options.offset;
    /** @type {import('./PreAggregations').PreAggregations} */
    this.preAggregations = this.newPreAggregations();
    /** @type {import('./BaseMeasure').BaseMeasure[]} */
    this.measures = (this.options.measures || []).map(this.newMeasure.bind(this));
    /** @type {import('./BaseDimension').BaseDimension[]} */
    this.dimensions = (this.options.dimensions || []).map(this.newDimension.bind(this));
    /** @type {import('./BaseDimension').BaseDimension[]} */
    this.multiStageDimensions = (this.options.multiStageDimensions || []).map(this.newDimension.bind(this));
    /** @type {import('./BaseTimeDimension').BaseTimeDimension[]} */
    this.multiStageTimeDimensions = (this.options.multiStageTimeDimensions || []).map(this.newTimeDimension.bind(this));
    /** @type {import('./BaseSegment').BaseSegment[]} */

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Use a valid IANA timezone name, e.g. 'America/New_York' or 'UTC'
  2. Map abbreviation inputs (EST, PST) to IANA names before sending
  3. Trim/format the string and check for typos against the tz database
  4. Update the runtime (Node/ICU) if a valid IANA name is still rejected

Example fix

// before
{ timezone: 'PST' }
// after
{ timezone: 'America/Los_Angeles' }
Defensive patterns

Strategy: validation

Validate before calling

function isValidTimezone(tz) {
  try { new Intl.DateTimeFormat('en-US', { timeZone: tz }); return true; }
  catch { return false; }
}
if (query.timezone && !isValidTimezone(query.timezone)) {
  query.timezone = 'UTC'; // or reject the request
}

Type guard

const isIanaTimezone = (tz) => typeof tz === 'string' && (() => { try { Intl.DateTimeFormat(undefined, { timeZone: tz }); return true; } catch { return false; } })();

Try / catch

try {
  await cube.query(query);
} catch (e) {
  if (/Incorrect timezone/.test(e.message)) {
    query.timezone = 'UTC';
    return cube.query(query);
  }
  throw e;
}

Prevention

When it happens

Trigger: Setting query.timezone (or the API gateway timezone parameter) to a value like 'PST', 'America', 'UTC+5 ' (malformed), or a locale name not resolvable by the Intl/IANA database.

Common situations: Accepting raw browser/device timezone strings from clients, abbreviations like 'EST'/'CET', typos such as 'Europ/Berlin', or environments with an outdated ICU/timezone database.

Related errors


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