{"record":{"id":"c5dd1d0e0b759144","repo":"hcengineering/platform","slug":"kvs-url-env-var-is-not-set","errorCode":null,"errorMessage":"KVS_URL env var is not set","messagePattern":"KVS_URL env var is not set","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"services/mail/pod-mail-worker/src/config.ts","lineNumber":57,"sourceCode":"const config: Config = {\n  port: parseInt(process.env.PORT ?? '4050'),\n  secret: process.env.SECRET ?? 'secret',\n  accountsUrl: process.env.ACCOUNTS_URL ?? 'http://localhost:3000',\n  workspaceUrl: (() => {\n    if (process.env.WORKSPACE_URL !== undefined) {\n      return process.env.WORKSPACE_URL\n    }\n    throw Error('WORKSPACE_URL env var is not set')\n  })(),\n  ignoredAddresses: process.env.IGNORED_ADDRESSES?.split(',') ?? [],\n  hookToken: process.env.HOOK_TOKEN,\n  mailSizeLimit: process.env.MAIL_SIZE_LIMIT ?? '50mb',\n  storageConfig: process.env.STORAGE_CONFIG,\n  kvsUrl: (() => {\n    if (process.env.KVS_URL !== undefined) {\n      return process.env.KVS_URL\n    }\n    throw Error('KVS_URL env var is not set')\n  })(),\n  queueConfig: (() => {\n    if (process.env.QUEUE_CONFIG !== undefined) {\n      return process.env.QUEUE_CONFIG\n    }\n    throw Error('QUEUE_CONFIG env var is not set')\n  })(),\n  queueRegion: process.env.QUEUE_REGION ?? '',\n  communicationTopic: process.env.COMMUNICATION_TOPIC ?? 'hulygun',\n  serviceId: process.env.SERVICE_ID ?? 'huly-mail',\n  mailUrl: (() => {\n    if (process.env.MAIL_URL !== undefined) {\n      return process.env.MAIL_URL\n    }\n    throw Error('MAIL_URL env var is not set')\n  })(),\n  mailAuth: process.env.MAIL_AUTH ?? '',\n  footerMessage: process.env.FOOTER_MESSAGE ?? '<br><br><p>Sent via <a href=\"https://huly.io\">Huly</a></p>',","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/mail/pod-mail-worker/src/config.ts#L39-L75","documentation":"In services/mail/pod-mail-worker/src/config.ts, kvsUrl is resolved by an inline IIFE that returns process.env.KVS_URL when defined and otherwise throws this error. KVS (key-value storage) access is mandatory for the mail worker, so the absence of KVS_URL aborts startup at import time.","triggerScenarios":"process.env.KVS_URL is undefined when config.ts is first imported. Empty string passes this check (only `!== undefined` is tested).","commonSituations":"KVS endpoint not injected into the pod's env; storage infra renamed/moved and KVS_URL removed; running the worker locally without the KVS portion of the .env.","solutions":["Set KVS_URL to the key-value storage service endpoint in the mail worker environment.","Confirm the KVS service is deployed and reachable from the worker's network.","Include KVS_URL in the local .env used for development runs.","Check the deployment secret/ConfigMap actually mounts KVS_URL into the container env."],"exampleFix":"// before\nKVS_URL unset -> throw at import\n// after\n# .env\nKVS_URL=http://kvs:3333","handlingStrategy":"validation","validationCode":"const required = ['KVS_URL', 'WORKSPACE_URL', 'QUEUE_CONFIG', 'MAIL_URL'];\nconst missing = required.filter((k) => process.env[k] === undefined);\nif (missing.length) {\n  console.error('Missing mail-worker env vars:', missing.join(', '));\n  process.exit(1);\n}\nnew URL(process.env.KVS_URL!);","typeGuard":"function isDefined<T>(v: T | undefined): v is T {\n  return v !== undefined;\n}","tryCatchPattern":"try {\n  const { default: config } = await import('./src/config.js');\n} catch (e) {\n  if ((e as Error).message === 'KVS_URL env var is not set') {\n    console.error('Configure KVS_URL pointing to the key-value storage service');\n  }\n  process.exit(1);\n}","preventionTips":["Inject KVS_URL from the same source that deploys the KVS service (consistent DNS/name).","Ping the KVS endpoint as part of startup health checks.","Document KVS_URL in the service deployment README."],"tags":["environment","configuration","startup","storage"],"backgroundTag":"missing-env-var","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}