{"record":{"id":"927895ce4495ff8f","repo":"affaan-m/ECC","slug":"open-requires-a-file-path","errorCode":null,"errorMessage":"open requires a file path","messagePattern":"open requires a file path","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/plan-canvas.js","lineNumber":225,"sourceCode":"    return false;\n  }\n}\n\nfunction output(payload) {\n  process.stdout.write(`${JSON.stringify(payload, null, 2)}\\n`);\n}\n\nasync function cmdStatus({ stateDir, port }) {\n  const health = await healthCheck(port);\n  if (!health) {\n    return { server: 'not running', hint: 'open an artifact to start one', stateDir };\n  }\n  const sessions = await request(port, 'GET', '/api/sessions');\n  return { server: `http://${DEFAULT_HOST}:${port}`, version: health.version, sessions: sessions.body.sessions };\n}\n\nasync function cmdOpen(file, args, { stateDir, port }) {\n  if (!file) throw new Error('open requires a file path');\n  if (!fs.existsSync(path.resolve(file))) throw new Error(`artifact not found: ${file}`);\n  await ensureServer({ stateDir, port });\n  const res = await request(port, 'POST', '/api/sessions', {\n    file: path.resolve(file),\n    reopen: args.includes('--reopen')\n  });\n  if (res.statusCode === 409) return res.body;\n  if (res.statusCode !== 200) throw new Error(res.body.error || `open failed (HTTP ${res.statusCode})`);\n  const url = `http://${DEFAULT_HOST}:${port}${res.body.url}`;\n  const launched = args.includes('--no-open') ? false : openBrowser(url);\n  return {\n    status: 'open',\n    url,\n    browser: launched ? 'opened' : 'not opened',\n    next_step:\n      'Run `ecc-plan-canvas await <file>` and leave it running; it returns when the human sends feedback, a verdict, or ends the session.'\n  };\n}","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/plan-canvas.js#L207-L243","documentation":"cmdOpen validates its inputs before touching the server: the first argument must be a file path. When invoked without a file (e.g. `plan-canvas open` with no operand), it throws this error instead of sending a malformed session-creation request.","triggerScenarios":"Running `node scripts/plan-canvas.js open` with no path argument; a wrapper script dropping its argument due to quoting (`open \"$FILE\"` with FILE empty); dispatching cmdOpen programmatically with undefined as the file parameter.","commonSituations":"CI jobs where the plan file variable is unset; shell aliases forgetting the argument; confusion between subcommands where `status` takes no file but `open` does.","solutions":["Pass the plan/artifact path: `node scripts/plan-canvas.js open <path-to-file>`.","Check the invoking script for an empty/unset variable holding the file path.","Confirm you are using the right subcommand — `status` doesn't need a file, `open` does.","Shell-quote the path so spaces don't split it into separate arguments."],"exampleFix":"// before\nFILE=\"\" ; node scripts/plan-canvas.js open \"$FILE\"\n// after\nFILE=\"docs/plan.html\" ; node scripts/plan-canvas.js open \"$FILE\"","handlingStrategy":"validation","validationCode":"const file = process.argv[3];\nif (!file) {\n  console.error('Usage: plan-canvas open <file>');\n  process.exit(2);\n}\nif (!fs.existsSync(path.resolve(file))) {\n  console.error(`artifact not found: ${file}`);\n  process.exit(2);\n}","typeGuard":"function hasFileArg(v) { return typeof v === 'string' && v.trim().length > 0; }","tryCatchPattern":"try {\n  await cmdOpen(file, args, { stateDir, port });\n} catch (err) {\n  if (err.message === 'open requires a file path') {\n    console.error('Usage: node scripts/plan-canvas.js open <file>');\n    process.exit(2);\n  }\n  throw err;\n}","preventionTips":["Quote \"$FILE\" in wrappers and fail fast if it is empty (`: \"${FILE:?unset}\"` in bash)","Document that `open` requires a file operand while `status` does not","Validate argument counts in wrapper scripts before dispatching subcommands"],"tags":["cli","missing-argument","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}