{"record":{"id":"f2559d82c58a4492","repo":"JuliusBrussee/caveman","slug":"invalid-caveman-listen-json-stringify-listen-expected-host","errorCode":null,"errorMessage":"invalid CAVEMAN_LISTEN ${JSON.stringify(listen)}; expected host:port","messagePattern":"invalid CAVEMAN_LISTEN (.+?); expected host:port","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":19033,"sourceCode":"  return new Promise((resolve) => {\n    const sock = netConnect({ host, port });\n    const finish = (v: boolean) => { sock.destroy(); resolve(v); };\n    sock.setTimeout(600);\n    sock.once(\"connect\", () => finish(true));\n    sock.once(\"timeout\", () => finish(false));\n    sock.once(\"error\", () => finish(false));\n  });\n}\n\nfunction standaloneProxyEndpoint(): { host: string; port: number; listen: string } {\n  const listen = (process.env.CAVEMAN_LISTEN ?? PROXY_ADDR).trim();\n  try {\n    const url = new URL(`http://${listen}`);\n    const port = Number(url.port);\n    if (!url.hostname || !Number.isInteger(port) || port < 1 || port > 65535 || url.pathname !== \"/\") throw new Error(\"invalid listener\");\n    return { host: url.hostname, port, listen };\n  } catch {\n    throw new Error(`invalid CAVEMAN_LISTEN ${JSON.stringify(listen)}; expected host:port`);\n  }\n}\n\nexport function gatewayHostPort(gw = gatewayURL()): { host: string; port: number } {\n  try {\n    const u = new URL(gw);\n    const defaultPort = u.protocol === \"https:\" ? 443 : 80;\n    return { host: u.hostname || \"127.0.0.1\", port: Number(u.port) || defaultPort };\n  } catch {\n    return { host: \"127.0.0.1\", port: 8787 };\n  }\n}\n\nfunction isCliEntrypoint(): boolean {\n  if (!process.argv[1]) return false;\n  const here = fileURLToPath(import.meta.url);\n  try {\n    return realpathSync(process.argv[1]) === here;","sourceCodeStart":19015,"sourceCodeEnd":19051,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/index.ts#L19015-L19051","documentation":"Thrown by standaloneProxyEndpoint() when the CAVEMAN_LISTEN environment variable cannot be interpreted as a host:port pair needed to bind the standalone Caveman proxy. The message includes the offending value JSON-quoted and states the expected 'host:port' format. It is the user-facing form of the internal 'invalid listener' guard.","triggerScenarios":"CAVEMAN_LISTEN is set (or defaults to PROXY_ADDR) and fails URL-based validation: missing hostname, port not an integer, port outside 1-65535, or a path suffix; or `new URL('http://' + listen)` itself throws.","commonSituations":" typos like CAVEMAN_LISTEN=\"localhost 8080\", \"localhost:\", \":8080\" (empty hostname), \"localhost:8080/\", quoted values with stray spaces, or a full URL pasted in instead of host:port.","solutions":["Set CAVEMAN_LISTEN to exactly host:port, e.g. CAVEMAN_LISTEN=0.0.0.0:8080.","Strip scheme, path, and whitespace from the value.","Use a valid port number (1-65535) that is not privileged (>1024 unless root).","Unset CAVEMAN_LISTEN to use the default listener address."],"exampleFix":"// before\nexport CAVEMAN_LISTEN=\"http://localhost:8080\"\ncaveman proxy   # throws invalid CAVEMAN_LISTEN \"http://localhost:8080\"; expected host:port\n// after\nexport CAVEMAN_LISTEN=\"localhost:8080\"\ncaveman proxy","handlingStrategy":"validation","validationCode":"const listen = process.env.CAVEMAN_LISTEN;\nif (listen && !/^[-.\\w]+:(\\d{1,5})$/.test(listen.trim()) || (listen && !(+listen.split(\":\")[1] >= 1 && +listen.split(\":\")[1] <= 65535))) {\n  throw new Error(`CAVEMAN_LISTEN \"${listen}\" is not host:port (e.g. 127.0.0.1:8080)`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  runProxy();\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith(\"invalid CAVEMAN_LISTEN\")) {\n    console.error(e.message, \"— expected e.g. CAVEMAN_LISTEN=127.0.0.1:8080\");\n  } else throw e;\n}","preventionTips":["Format CAVEMAN_LISTEN as host:port only (no http://, no path, no spaces)","Use ports 1-65535; prefer >=1024 to avoid privileged-port issues","Quote env values carefully in shells to avoid stray whitespace","Unset CAVEMAN_LISTEN to accept the default PROXY_ADDR"],"tags":["configuration","env","cli","url"],"backgroundTag":"invalid-env-var-value","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}