{"record":{"id":"7c5b5910302abbfb","repo":"affaan-m/ECC","slug":"invalid-plan-canvas-server-port-port","errorCode":null,"errorMessage":"invalid plan-canvas server port: ${port}","messagePattern":"invalid plan-canvas server port: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/plan-canvas.js","lineNumber":96,"sourceCode":"  return index >= 0 && index + 1 < args.length ? args[index + 1] : null;\n}\n\nfunction serverInfoPath(stateDir) {\n  return path.join(stateDir, 'server.json');\n}\n\nfunction readServerInfo(stateDir) {\n  try {\n    return JSON.parse(fs.readFileSync(serverInfoPath(stateDir), 'utf8'));\n  } catch {\n    return null;\n  }\n}\n\nfunction validatePort(port) {\n  const value = Number(port);\n  if (!Number.isInteger(value) || value < 0 || value > 65535) {\n    throw new Error(`invalid plan-canvas server port: ${port}`);\n  }\n  return value;\n}\n\nfunction validateRequestPath(requestPath) {\n  if (typeof requestPath !== 'string' || !requestPath.startsWith('/')) {\n    throw new Error('plan-canvas request path must be root-relative');\n  }\n  const url = new URL(requestPath, `http://${DEFAULT_HOST}`);\n  if (url.hostname !== DEFAULT_HOST) {\n    throw new Error('plan-canvas request path must stay on the loopback server');\n  }\n  if (!SAFE_REQUEST_PATHS.has(url.pathname) && !SESSION_REPLY_PATH.test(url.pathname)) {\n    throw new Error(`unsupported plan-canvas request path: ${url.pathname}`);\n  }\n  return `${url.pathname}${url.search}`;\n}\n","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/plan-canvas.js#L78-L114","documentation":"Thrown by validatePort in scripts/plan-canvas.js when the supplied port is not an integer in the range 0-65535. validatePort is called from requestOptions on every outbound HTTP request to the canvas server, so a bad port from server.json, the environment (ECC_PLAN_CANVAS_PORT), or the --port flag triggers it.","triggerScenarios":"Setting ECC_PLAN_CANVAS_PORT to a non-numeric, float, or out-of-range value; passing `--port 99999` or `--port abc`; a corrupted server.json recording a malformed port. Number(port) accepts numeric strings but rejects mixed strings to NaN, which then fails Number.isInteger.","commonSituations":"Env var misconfiguration in CI; a stale/corrupted server.json after a crash; passing 0 is allowed (ephemeral bind) but negatives and >65535 are not.","solutions":["Set a valid port: `--port 4319` or `ECC_PLAN_CANVAS_PORT=4319`.","If server.json is corrupted, run `node scripts/plan-canvas.js stop` or delete the state directory to reset it.","Validate env-provided ports upstream with an integer-range check before invoking the CLI."],"exampleFix":"// before\nECC_PLAN_CANVAS_PORT=99999 node scripts/plan-canvas.js open plan.md\n// after\nECC_PLAN_CANVAS_PORT=4319 node scripts/plan-canvas.js open plan.md","handlingStrategy":"validation","validationCode":"function normalizePort(raw) {\n  const n = Number(raw);\n  if (!Number.isInteger(n) || n < 0 || n > 65535) {\n    throw new Error(`Invalid port: ${raw}. Must be an integer in 0..65535.`);\n  }\n  return n;\n}","typeGuard":"function isPort(value) {\n  const n = Number(value);\n  return Number.isInteger(n) && n >= 0 && n <= 65535;\n}","tryCatchPattern":null,"preventionTips":["Validate ECC_PLAN_CANVAS_PORT in your environment setup before invoking the CLI.","If a stale server.json holds a bad port, run `plan-canvas stop` or remove the state dir.","Avoid privileged ports (<1024) unless you specifically intend them; the CLI allows them but the OS may not."],"tags":["cli","plan-canvas","network","validation","port"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}