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

  1. Pass the plan/artifact file as the first positional argument: `node scripts/plan-canvas.js await .claude/plans/feature.plan.md`.
  2. If wrapping the call in a script, guard the file variable before invoking: `if [ -z "$FILE" ]; then exit 1; fi`.
  3. 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

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


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/6d6662f0dcd64635. Report an issue: GitHub.