hcengineering/platform · error · Error

Missing env variables: ${missingEnv.join(', ')}

Error message

Missing env variables: ${missingEnv.join(', ')}

What it means

The pod-calendar config IIFE builds params from env vars and throws 'Missing env variables' (reporting the mapped env-var names via envMap) when any param is undefined. Port, ServiceID, InitLimit and WorkspaceInactivityInterval have defaults, so the throw comes from ACCOUNTS_URL, SECRET, Credentials, WATCH_URL, or KVS_URL being unset.

Source

Thrown at services/calendar/pod-calendar/src/config.ts:62

const config: Config = (() => {
  const params: Partial<Config> = {
    Port: parseNumber(process.env[envMap.Port]) ?? 8095,
    AccountsURL: process.env[envMap.AccountsURL],
    ServiceID: process.env[envMap.ServiceID] ?? 'calendar-service',
    Secret: process.env[envMap.Secret],
    Credentials: process.env[envMap.Credentials],
    InitLimit: parseNumber(process.env[envMap.InitLimit]) ?? 50,
    WATCH_URL: process.env[envMap.WATCH_URL],
    KvsUrl: process.env[envMap.KvsUrl],
    WorkspaceInactivityInterval: parseNumber(process.env[envMap.WorkspaceInactivityInterval] ?? '3') // In days
  }

  const missingEnv = (Object.keys(params) as Array<keyof Config>)
    .filter((key) => params[key] === undefined)
    .map((key) => envMap[key])

  if (missingEnv.length > 0) {
    throw Error(`Missing env variables: ${missingEnv.join(', ')}`)
  }

  return params as Config
})()

export default config

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Set the env vars named in the message — typically ACCOUNTS_URL, SECRET, Credentials, WATCH_URL, KVS_URL.
  2. Check the env key is exactly 'Credentials' (mixed case) — a case typo causes this error.
  3. Verify k8s Secret/ConfigMap mounts contain all calendar-related keys.
  4. Create a local .env with these vars before running the pod.

Example fix

// before
export CREDENTIALS=$CREDS  # wrong case; WATCH_URL also missing
// after
export Credentials=$(cat google-creds.json)
export WATCH_URL=https://calendar.example.com/watch
export KVS_URL=https://kvs.example.com
export SECRET=...
export ACCOUNTS_URL=https://accounts.example.com
Defensive patterns

Strategy: validation

Validate before calling

const missing = ['ACCOUNTS_URL','SECRET','Credentials','WATCH_URL','KVS_URL'].filter((k) => process.env[k] === undefined)
if (missing.length > 0) throw new Error(`Missing env variables: ${missing.join(', ')}`)

Type guard

function hasEnv(key: string): boolean {
  return process.env[key] !== undefined
}

Try / catch

try {
  const { default: config } = await import('./config.js')
} catch (err) {
  if ((err as Error).message.startsWith('Missing env variables:')) {
    console.error('calendar config error:', err.message)
    process.exit(1)
  }
  throw err
}

Prevention

When it happens

Trigger: Importing services/calendar/pod-calendar/src/config.ts without one of: ACCOUNTS_URL, SECRET, Credentials, WATCH_URL, KVS_URL. The message reports env-var names (e.g. 'Credentials, WATCH_URL'). Note the credentials env var is literally 'Credentials' (mixed case) per envMap.

Common situations: Deploying calendar service without Google/Calendar API credentials; missing KVS or watch URL after infrastructure changes; secret not mounted; typo like CREDENTIALS (uppercase) instead of Credentials.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/8e15db1a41554f32. Report an issue: GitHub.