{"record":{"id":"338010ee18720f92","repo":"affaan-m/ECC","slug":"end-requires-a-file-path","errorCode":null,"errorMessage":"end requires a file path","messagePattern":"end requires a file path","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/plan-canvas.js","lineNumber":329,"sourceCode":"// Report feedback the human sent that no agent has picked up yet. Reads state\n// directly so it answers even when the server has idled out.\nfunction cmdPending({ stateDir }) {\n  const store = createSessionStore({ stateDir });\n  const waiting = store\n    .list()\n    .filter(session => session.status !== 'ended' && session.pending > 0)\n    .map(session => ({ file: session.file, pending: session.pending, updatedAt: session.updatedAt }));\n  return {\n    status: waiting.length ? 'pending' : 'clear',\n    sessions: waiting,\n    next_step: waiting.length\n      ? 'Run `ecc-plan-canvas await <file>` for each file above to receive the messages.'\n      : 'No canvas feedback is waiting.'\n  };\n}\n\nasync function cmdEnd(file, { port }) {\n  if (!file) throw new Error('end requires a file path');\n  if (!(await healthCheck(port))) return { status: 'no-server' };\n  const res = await request(port, 'POST', '/api/end', { file: path.resolve(file) });\n  return res.body;\n}\n\nasync function cmdStop({ stateDir, port }) {\n  if (!(await healthCheck(port))) return { status: 'not running' };\n  await request(port, 'POST', '/shutdown').catch(() => {});\n  fs.rmSync(serverInfoPath(stateDir), { force: true });\n  return { status: 'stopping' };\n}\n\nasync function cmdServer(args, { stateDir, port }) {\n  const portArg = valueAfter(args, '--port');\n  const hostArg = valueAfter(args, '--host');\n  const listenPort = portArg !== null ? Number.parseInt(portArg, 10) : port;\n  const store = createSessionStore({ stateDir });\n  let shuttingDown = false;","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/plan-canvas.js#L311-L347","documentation":"Thrown by cmdEnd when the `end` subcommand is called without a positional file path. The end command POSTs to `/api/end` with `path.resolve(file)`, so a file is mandatory to identify which review session to terminate. It is the agent-side way to close a session after delivering final updates.","triggerScenarios":"Running `node scripts/plan-canvas.js end` with no file; passing a flag in the file slot; a cleanup hook that calls end generically without knowing which plan was open.","commonSituations":"Agent shutdown routine calls `end` for all sessions but one file variable was empty; user misreads usage and thinks `end` with no arg ends all; orphaned session from a crashed `open` that the caller tries to end by name that no longer exists.","solutions":["Pass the file: `node scripts/plan-canvas.js end .claude/plans/feature.plan.md`.","If you need to stop the whole server regardless of session, use `node scripts/plan-canvas.js stop` instead.","Track open files in your orchestrator so the end call always has a concrete path."],"exampleFix":"// before\nnode scripts/plan-canvas.js end\n// after\nnode scripts/plan-canvas.js end .claude/plans/feature.plan.md","handlingStrategy":"validation","validationCode":"function validateEndFile(file) {\n  if (typeof file !== 'string' || file.trim() === '') {\n    throw new Error('cmdEnd: file argument is required');\n  }\n  return file;\n}","typeGuard":"function isEndFile(arg) {\n  return typeof arg === 'string' && arg.length > 0 && !arg.startsWith('--');\n}","tryCatchPattern":"try {\n  await cmdEnd(file, ctx);\n} catch (err) {\n  if (err.message === 'end requires a file path') {\n    console.error('Usage: node scripts/plan-canvas.js end <file>');\n    process.exit(2);\n  }\n  throw err;\n}","preventionTips":["Use `stop` (no file) to shut the whole server; use `end <file>` for one session.","Track open files in the orchestrator so end always has a concrete path.","Make end idempotent-safe by tolerating 'session not found' from the server."],"tags":["cli","argument-validation","plan-canvas","lifecycle"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}