affaan-m/ECC · error · Error
await requires a file path
Error message
await requires a file path
What it means
Thrown by cmdAwait in the Plan Canvas CLI when the `await` subcommand is invoked without a positional file argument. The await command long-polls the local canvas server for human feedback on a specific plan/artifact, so it must know which file's review session to wait on. Without a file there is no session key to bind the poll to.
Source
Thrown at scripts/plan-canvas.js:273
data += chunk;
});
res.on('end', () => {
try {
resolve(JSON.parse(data.trim()));
} catch {
reject(new Error('await response was not JSON (server restarted?) - re-run await; feedback is never lost'));
}
});
}
);
req.setTimeout(0);
req.on('error', reject);
req.end();
});
}
async function cmdAwait(file, args, { stateDir, port }) {
if (!file) throw new Error('await requires a file path');
if (!(await healthCheck(port))) {
return { status: 'no-server', hint: 'no canvas server is running; use `open` first', stateDir };
}
const reply = valueAfter(args, '--reply');
if (reply) {
const key = sessionKeyFor(canonicalizeArtifactPath(file));
await request(port, 'POST', `/api/session/${key}/reply`, { text: reply });
}
const timeoutRaw = valueAfter(args, '--timeout-ms');
const timeoutMs = timeoutRaw === null ? null : Number.parseInt(timeoutRaw, 10) || 0;
process.stderr.write('[plan-canvas] waiting for human feedback... leave this running (re-run if interrupted; queued feedback is never lost)\n');
const result = await awaitRequest(port, sessionKeyFor(canonicalizeArtifactPath(file)), timeoutMs);
if (result.status === 'feedback') {
result.next_step = result.sessionEnded
? 'The user sent this feedback and ended the session. Address it and report in chat; do not reopen the canvas uninvited.'
: 'Address the feedback, then run `ecc-plan-canvas await <file> --reply "<what you changed>"` to answer in the canvas and keep listening.';
} else if (result.status === 'ended') {
result.next_step =View on GitHub (pinned to 01e15490f0)
Solutions
- Pass the plan/artifact file as the first positional argument: `node scripts/plan-canvas.js await .claude/plans/feature.plan.md`.
- If wrapping the call in a script, guard the file variable before invoking: `if [ -z "$FILE" ]; then exit 1; fi`.
- Run `node scripts/plan-canvas.js` with no args (or --help) to see the usage block listing required positional args per subcommand.
Example fix
// before node scripts/plan-canvas.js await --reply "done" // after node scripts/plan-canvas.js await .claude/plans/feature.plan.md --reply "done"
Defensive patterns
Strategy: validation
Validate before calling
// Before calling cmdAwait, ensure file is a non-empty string
function validateAwaitArgs(file) {
if (typeof file !== 'string' || file.trim() === '') {
throw new Error('cmdAwait: file argument is required (e.g. .claude/plans/feature.plan.md)');
}
return file;
} Type guard
// Narrow a CLI positional to a valid await file
function isAwaitFile(arg) {
return typeof arg === 'string' && arg.length > 0 && !arg.startsWith('--');
} Try / catch
// Wrap the subcommand dispatch so a missing-file usage error surfaces as a clean exit
try {
await cmdAwait(file, args, ctx);
} catch (err) {
if (err.message === 'await requires a file path') {
console.error('Usage: node scripts/plan-canvas.js await <file> [--reply text] [--timeout-ms n]');
process.exit(2);
}
throw err;
} Prevention
- Always pass the plan file as the first positional after the `await` subcommand.
- In agent harnesses, assert the file variable is set before invoking plan-canvas.
- Keep a list of open files in the orchestrator so await/end always reference a real path.
When it happens
Trigger: Running `node scripts/plan-canvas.js await` with no positional arg; passing only flags like `--reply` or `--timeout-ms` but no file path first; a wrapper script that interpolates an empty/undefined file variable.
Common situations: Agent harness invokes plan-canvas with a variable that resolved to empty; user forgets the file after copying a flag-only example; CI runs `await` against a glob that matched nothing.
Related errors
- open requires a file path
- typing requires a file path
- end requires a file path
- Unknown argument: ${arg}
- Unknown argument: ${arg}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/6d6662f0dcd64635.
Report an issue: GitHub.