cube-js/cube · error · TypeError
Timezone must not be empty
Error message
Timezone must not be empty
What it means
canonicalTimezone rejects an empty-string timezone with 'Timezone must not be empty'. An empty string would otherwise fall through to moment.tz.zone('') which yields no zone and returns null, hiding a configuration problem; the library chooses to fail loudly instead so callers fix the source of the empty value.
Source
Thrown at packages/cubejs-backend-shared/src/timezone.ts:19
import moment from 'moment-timezone';
/**
* Resolves `value` to a canonical tz-database zone name, matched case-insensitively,
* or `null` when it is unset or not a known zone.
*
* @throws {TypeError} when `value` is an empty string, or is neither a string nor unset.
*/
export function canonicalTimezone(value?: string | null): string | null {
if (value === undefined || value === null) {
return null;
}
if (typeof value !== 'string') {
throw new TypeError(`Timezone must be a string, got ${typeof value}`);
}
if (value === '') {
throw new TypeError('Timezone must not be empty');
}
const zone = moment.tz.zone(value);
return zone ? zone.name : null;
}
View on GitHub (pinned to 7d981676b3)
Solutions
- Fix the source: populate the timezone config/env/form field with a valid IANA name (e.g. 'UTC').
- Treat empty as absent at the call site: pass null/undefined instead of '' when no timezone is configured.
- Add config-load validation that requires a non-empty timezone if the field is mandatory.
- Normalize whitespace-only strings to null before calling (value.trim() === '' → null).
Example fix
// before canonicalTimezone(process.env.TZ_NAME || ''); // '' → TypeError // after const tz = process.env.TZ_NAME?.trim() || null; canonicalTimezone(tz); // null is the sanctioned 'no timezone' value
Defensive patterns
Strategy: validation
Validate before calling
function normalizeTimezoneInput(v: string | null | undefined): string | null {
const s = typeof v === 'string' ? v.trim() : v;
return s ? s : null; // empty/whitespace becomes the sanctioned 'absent' value
} Type guard
function isNonEmptyString(v: unknown): v is string {
return typeof v === 'string' && v.trim().length > 0;
} Try / catch
try {
return canonicalTimezone(raw);
} catch (e) {
if (e instanceof TypeError && /must not be empty/.test(e.message)) {
console.warn('Empty timezone configured; treating as unset');
return null;
}
throw e;
} Prevention
- Require timezone fields in .env and fail fast at startup if empty
- Use null/undefined (not '') for 'no timezone' semantics
- Trim whitespace-only strings before passing
- Validate forms/UI so an empty preference is stored as null
When it happens
Trigger: canonicalTimezone('') — typically from empty env vars (TZ_NAME=''), blank form fields, or default-destructured values that resolve to ''.
Common situations: Missing env var defaulting to empty string; UI saving an empty timezone preference; YAML/JSON config with `timezone:` left blank; `.env` file with TZ= set but empty.
Related errors
- Value "${raw}" is not valid for CUBEJS_SCHEDULED_REFRESH_TIM
- Value "${value}" is not valid for CUBEJS_DEFAULT_TIMEZONE. M
- Unknown timezone: ${timezone}
- Timezone must be a string, got ${typeof value}
- Incorrect timezone ${this.timezone}
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/ae7d22ba649e05fc.
Report an issue: GitHub.