{"record":{"id":"31716a98004bb77e","repo":"hcengineering/platform","slug":"missing-env-variables-missingenv-join-31716a","errorCode":null,"errorMessage":"Missing env variables: ${missingEnv.join(', ')}","messagePattern":"Missing env variables: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"services/love/src/config.ts","lineNumber":86,"sourceCode":"    StorageConfig: process.env[envMap.StorageConfig],\n    StorageProviderName: process.env[envMap.StorageProviderName] ?? 's3',\n    S3StorageConfig: process.env[envMap.S3StorageConfig],\n    Secret: process.env[envMap.Secret],\n    ServiceID: process.env[envMap.ServiceID] ?? 'love-service',\n    RecordingPreset: process.env[envMap.RecordingPreset] ?? '720p',\n    BillingUrl: process.env[envMap.BillingUrl] ?? '',\n    BillingPollInterval: parseNumber(process.env[envMap.BillingPollInterval]) ?? 15\n  }\n\n  const optional = ['StorageConfig', 'S3StorageConfig', 'LiveKitProject', 'BillingUrl']\n\n  const missingEnv = (Object.keys(params) as Array<keyof Config>)\n    .filter((key) => !optional.includes(key))\n    .filter((key) => params[key] === undefined)\n    .map((key) => envMap[key])\n\n  if (missingEnv.length > 0) {\n    throw Error(`Missing env variables: ${missingEnv.join(', ')}`)\n  }\n\n  return params as Config\n})()\n\nexport default config\n","sourceCodeStart":68,"sourceCodeEnd":93,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/love/src/config.ts#L68-L93","documentation":"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.","triggerScenarios":"A required (not in `optional`) env var is undefined when config.ts is imported; the error names the envMap entries for each missing key.","commonSituations":"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.","solutions":["Set each env variable named in the error message in the runtime environment.","If a variable is genuinely optional, add its Config key to the `optional` array in config.ts (code change) rather than leaving it unset.","After upgrading the service, diff its config.ts against the previous version to find newly required vars.","Verify locally that importing the config module succeeds with your .env."],"exampleFix":"// before\nNEW_REQUIRED_URL unset -> throw at import\n// after\n# .env\nNEW_REQUIRED_URL=https://accounts.example.com\n// or, in config.ts\nconst optional = [...existing, 'NewRequiredUrl']","handlingStrategy":"validation","validationCode":"// Required list = envMap keys minus the service's `optional` array\nconst optional: string[] = [/* from services/love/src/config.ts */];\nconst required: string[] = [/* all envMap values */].filter((k) => !optional.includes(k));\nconst missing = required.filter((k) => process.env[k] === undefined);\nif (missing.length) throw new Error(`Missing env variables: ${missing.join(', ')}`);","typeGuard":"function hasAllEnv(keys: readonly string[]): boolean {\n  return keys.every((k) => process.env[k] !== undefined);\n}","tryCatchPattern":"try {\n  const { default: config } = await import('./src/config.js');\n} catch (e) {\n  console.error(`Love service config error: ${(e as Error).message}`);\n  process.exit(1);\n}","preventionTips":["When adding a config key, decide explicitly: default, optional, or required.","After upgrades, diff the required-var set and update the deployment env.","Run a CI job that imports the config module with a canonical dummy env."],"tags":["environment","configuration","startup"],"backgroundTag":"missing-env-var","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}