pbakaus/impeccable · error

serve-question: --start needs --payload <file>

Error message

serve-question: --start needs --payload <file>

What it means

--start launches a live question page but requires --payload <file> pointing at the JSON describing the question (question text and options). Without it, run() prints this message and exits 1 before creating any question directory or server.

Source

Thrown at crates/context/src/serve_question.rs:319

        let ok = next_round.get("options").and_then(|o| o.as_array()).map(|o| !o.is_empty()).unwrap_or(false);
        if !ok {
            io.err("serve-question: --update payload needs an options array; nothing was delivered. Fix the payload and rerun --update on the same key.\n");
            return 1;
        }
        if !is_alive(&qdir, &key) {
            io.err("serve-question: no live question server for that key; the page it served is gone too. Re-present the round with --start and a fresh key, or fall back to the structured question tool.\n");
            return 2;
        }
        let delivered = next_file(&qdir, &key);
        let _ = std::fs::copy(jsp::resolve(&cwd, &[&pp]), &delivered);
        touch_now(&delivered);
        io.out("next round delivered; the page reloads itself\n");
        return 0;
    }

    if a.has("start") {
        let Some(pp) = payload_path.clone() else {
            io.err("serve-question: --start needs --payload <file>\n");
            return 1;
        };
        if let Err(msg) = read_json_file(&jsp::resolve(&cwd, &[&pp])) {
            io.err(&format!("{}\n", msg));
            return 1;
        }
        let _ = std::fs::create_dir_all(&qdir);
        let key = a.arg("key").unwrap_or_else(random_key);
        let log_file = jsp::join(&[&qdir, &format!("{}.log", key)]);
        let log = std::fs::OpenOptions::new().append(true).create(true).open(&log_file);
        let exe = std::env::current_exe().map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "impeccable".to_string());
        let mut child_args: Vec<String> = vec![
            "serve-question".into(),
            "--payload".into(),
            pp.clone(),
            "--detached-serve".into(),
            "--key".into(),
            key.clone(),

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Pass --payload with the path to a JSON file containing the question and a non-empty options array.
  2. Create the payload JSON first if it does not exist.
  3. Guard the payload path in scripts before invoking serve-question.

Example fix

// before
serve-question --start --key q-1
// after
serve-question --start --key q-1 --payload question.json
Defensive patterns

Strategy: validation

Validate before calling

if (args.includes('--start') && !args.includes('--payload')) {
  throw new Error('serve-question --start requires --payload <file>');
}

Type guard

null

Try / catch

const res = spawnSync('serve-question', args);
if (res.status === 1 && res.stderr.includes('--start needs --payload')) {
  // write the question payload JSON, then retry --start
}

Prevention

When it happens

Trigger: Invoking `serve-question --start` (with or without --key) but omitting the `--payload <file>` argument.

Common situations: First-time users assuming a default question payload; scripts where the payload path variable is unset; copy-pasting a start command and dropping the payload argument.

Understand the failure class

Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.

Related errors


AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08). Data as JSON: /api/errors/482e6c00ae7079ff. Report an issue: GitHub.