hcengineering/platform · critical · Error

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

Error message

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

What it means

The love service config module (services/love/src/config.ts) builds params at import time and validates it, but unlike other services it consults an `optional` array: keys listed there may be undefined. Any non-optional key whose value is undefined is mapped through envMap and reported in this error. It is an import-time fail-fast guard for required configuration.

Source

Thrown at services/love/src/config.ts:86

    StorageConfig: process.env[envMap.StorageConfig],
    StorageProviderName: process.env[envMap.StorageProviderName] ?? 's3',
    S3StorageConfig: process.env[envMap.S3StorageConfig],
    Secret: process.env[envMap.Secret],
    ServiceID: process.env[envMap.ServiceID] ?? 'love-service',
    RecordingPreset: process.env[envMap.RecordingPreset] ?? '720p',
    BillingUrl: process.env[envMap.BillingUrl] ?? '',
    BillingPollInterval: parseNumber(process.env[envMap.BillingPollInterval]) ?? 15
  }

  const optional = ['StorageConfig', 'S3StorageConfig', 'LiveKitProject', 'BillingUrl']

  const missingEnv = (Object.keys(params) as Array<keyof Config>)
    .filter((key) => !optional.includes(key))
    .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 each env variable named in the error message in the runtime environment.
  2. If a variable is genuinely optional, add its Config key to the `optional` array in config.ts (code change) rather than leaving it unset.
  3. After upgrading the service, diff its config.ts against the previous version to find newly required vars.
  4. Verify locally that importing the config module succeeds with your .env.

Example fix

// before
NEW_REQUIRED_URL unset -> throw at import
// after
# .env
NEW_REQUIRED_URL=https://accounts.example.com
// or, in config.ts
const optional = [...existing, 'NewRequiredUrl']
Defensive patterns

Strategy: validation

Validate before calling

// Required list = envMap keys minus the service's `optional` array
const optional: string[] = [/* from services/love/src/config.ts */];
const required: string[] = [/* all envMap values */].filter((k) => !optional.includes(k));
const missing = required.filter((k) => process.env[k] === undefined);
if (missing.length) throw new Error(`Missing env variables: ${missing.join(', ')}`);

Type guard

function hasAllEnv(keys: readonly string[]): boolean {
  return keys.every((k) => process.env[k] !== undefined);
}

Try / catch

try {
  const { default: config } = await import('./src/config.js');
} catch (e) {
  console.error(`Love service config error: ${(e as Error).message}`);
  process.exit(1);
}

Prevention

When it happens

Trigger: A required (not in `optional`) env var is undefined when config.ts is imported; the error names the envMap entries for each missing key.

Common situations: Love service deployed without a newly added required env var after an upgrade; optional var mistakenly assumed to be optional but not listed in `optional`; incomplete local .env.

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/31716a98004bb77e. Report an issue: GitHub.