{"record":{"id":"4cbaf7e5bb088a37","repo":"Hmbown/CodeWhale","slug":"names-join-or-is-required","errorCode":null,"errorMessage":"${names.join(\" or \")} is required","messagePattern":"(.+?) is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"integrations/telegram-bridge/src/index.mjs","lineNumber":985,"sourceCode":"    error.description = payload?.description || \"\";\n    error.parameters = payload?.parameters || {};\n    throw error;\n  }\n  return payload.result;\n}\n\nfunction requiredEnv(name) {\n  const value = process.env[name];\n  if (!value || !value.trim()) {\n    throw new Error(`${name} is required`);\n  }\n  return value.trim();\n}\n\nfunction requiredEnvFirst(...names) {\n  const value = envFirst(process.env, ...names);\n  if (!value) {\n    throw new Error(`${names.join(\" or \")} is required`);\n  }\n  return value;\n}\n\nfunction delay(ms) {\n  return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","sourceCodeStart":967,"sourceCodeEnd":993,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/integrations/telegram-bridge/src/index.mjs#L967-L993","documentation":"requiredEnvFirst(...names) accepts the first non-empty value among alternative env names and throws `${names.join(\" or \")} is required` when every name is missing. The telegram bridge uses it for the runtime token: requiredEnvFirst(\"CODEWHALE_RUNTIME_TOKEN\", \"DEEPSEEK_RUNTIME_TOKEN\") at index.mjs:51, so the message reads 'CODEWHALE_RUNTIME_TOKEN or DEEPSEEK_RUNTIME_TOKEN is required'.","triggerScenarios":"Starting the bridge with neither CODEWHALE_RUNTIME_TOKEN nor DEEPSEEK_RUNTIME_TOKEN set, or with both blank (empty-string or whitespace-only values).","commonSituations":"Migrating deployments from the legacy DEEPSEEK_* variable names to CODEWHALE_*; an env template that predates the rename; pointing the bridge at a token-protected runtime without provisioning a token.","solutions":["Set the canonical name: `export CODEWHALE_RUNTIME_TOKEN=<token issued by the runtime>`","During migration, mirror the value to DEEPSEEK_RUNTIME_TOKEN so older tooling keeps working","Check what the service manager actually injects (`systemctl show <unit> -p Environment`, `docker inspect`) — the name may be missing or misspelled"],"exampleFix":"# before: only the legacy name, blank\nexport DEEPSEEK_RUNTIME_TOKEN=\n# after\nexport CODEWHALE_RUNTIME_TOKEN='s3cr3t'","handlingStrategy":"validation","validationCode":"const runtimeToken = ['CODEWHALE_RUNTIME_TOKEN', 'DEEPSEEK_RUNTIME_TOKEN']\n  .map((name) => process.env[name]?.trim())\n  .find(Boolean);\nif (!runtimeToken) {\n  console.error('Set CODEWHALE_RUNTIME_TOKEN (or legacy DEEPSEEK_RUNTIME_TOKEN)');\n  process.exit(2);\n}","typeGuard":null,"tryCatchPattern":"try {\n  startBridge();\n} catch (error) {\n  if (/CODEWHALE_RUNTIME_TOKEN or DEEPSEEK_RUNTIME_TOKEN is required/.test(error.message)) {\n    process.exit(2);\n  }\n  throw error;\n}","preventionTips":["Set the canonical CODEWHALE_* name and mirror legacy names during migration","Audit service-manager env blocks after any variable rename"],"tags":["environment","config","validation","migration","telegram-bridge"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}