{"record":{"id":"ae7d22ba649e05fc","repo":"cube-js/cube","slug":"timezone-must-not-be-empty","errorCode":null,"errorMessage":"Timezone must not be empty","messagePattern":"Timezone must not be empty","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-backend-shared/src/timezone.ts","lineNumber":19,"sourceCode":"import moment from 'moment-timezone';\n\n/**\n * Resolves `value` to a canonical tz-database zone name, matched case-insensitively,\n * or `null` when it is unset or not a known zone.\n *\n * @throws {TypeError} when `value` is an empty string, or is neither a string nor unset.\n */\nexport function canonicalTimezone(value?: string | null): string | null {\n  if (value === undefined || value === null) {\n    return null;\n  }\n\n  if (typeof value !== 'string') {\n    throw new TypeError(`Timezone must be a string, got ${typeof value}`);\n  }\n\n  if (value === '') {\n    throw new TypeError('Timezone must not be empty');\n  }\n\n  const zone = moment.tz.zone(value);\n\n  return zone ? zone.name : null;\n}\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-backend-shared/src/timezone.ts#L1-L26","documentation":"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.","triggerScenarios":"canonicalTimezone('') — typically from empty env vars (TZ_NAME=''), blank form fields, or default-destructured values that resolve to ''.","commonSituations":"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.","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)."],"exampleFix":"// before\ncanonicalTimezone(process.env.TZ_NAME || ''); // '' → TypeError\n\n// after\nconst tz = process.env.TZ_NAME?.trim() || null;\ncanonicalTimezone(tz); // null is the sanctioned 'no timezone' value","handlingStrategy":"validation","validationCode":"function normalizeTimezoneInput(v: string | null | undefined): string | null {\n  const s = typeof v === 'string' ? v.trim() : v;\n  return s ? s : null; // empty/whitespace becomes the sanctioned 'absent' value\n}","typeGuard":"function isNonEmptyString(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  return canonicalTimezone(raw);\n} catch (e) {\n  if (e instanceof TypeError && /must not be empty/.test(e.message)) {\n    console.warn('Empty timezone configured; treating as unset');\n    return null;\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["timezone","empty-string","validation","config"],"backgroundTag":"empty-timezone","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}