pbakaus/impeccable · error

serve-question: server failed to start{}

Error message

serve-question: server failed to start{}

What it means

The `serve-question` subcommand starts a local HTTP server on 127.0.0.1 to serve a question payload; when that server fails to start, this error prints the last 4 lines of the server log tail (if any) and points at the full log file. It exists so agents/harnesses can diagnose why a localhost listener could not come up. Exit code is 1.

Source

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

            }
            // JS: spawn(..., { detached: true }) + child.unref()
            impeccable_common::proc::detach(&mut cmd);
            cmd.spawn()
        };
        let _ = spawned; // detached: never waited on
        let deadline = now_ms() + 8000.0;
        while now_ms() < deadline && !exists(&state_file(&qdir, &key)) {
            sleep_ms(100);
        }
        if !exists(&state_file(&qdir, &key)) {
            let tail = safe_read(&log_file)
                .map(|t| {
                    let lines: Vec<&str> = crate::util::js_trim(&t).split('\n').collect();
                    let n = lines.len();
                    lines[n.saturating_sub(4)..].join("\n  ")
                })
                .unwrap_or_default();
            io.err(&format!("serve-question: server failed to start{}\n", if tail.is_empty() { String::new() } else { format!("\n  {}", tail) }));
            let rel = jsp::relative(&cwd, &cwd, &log_file);
            io.err(&format!("serve-question: log at {}. A sandboxed exec that cannot listen on localhost causes exactly this; rerun this command once through the harness's network-enabled or unsandboxed command tool before falling back.\n", if rel.is_empty() { log_file.clone() } else { rel }));
            return 1;
        }
        let state = read_state(&qdir, &key).unwrap_or_default();
        io.out(&format!("QUESTION URL: {}\n", state.get("url").map(js_str).unwrap_or_default()));
        io.out(&format!("QUESTION KEY: {}\n", key));
        io.out("Open the URL for the user now: in-app browser when the harness has one, otherwise the system opener (macOS `open`, Linux `xdg-open`), otherwise show the URL.\n");
        io.out(&format!("Then collect the answer with: {} --wait --key {}\n", crate::provider::detect(&env, &cwd).verb_cmd("serve-question"), key));
        return 0;
    }

    // ---- server (blocking or detached) ----
    let raw = match &payload_path {
        Some(pp) => match std::fs::read(jsp::resolve(&cwd, &[pp])) {
            Ok(b) => String::from_utf8_lossy(&b).into_owned(),
            Err(e) => {
                io.err(&format!("Error: {}\n", crate::util::node_read_error(pp, &e)));

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Rerun the command once through the harness's network-enabled or unsandboxed command tool (as the error itself instructs).
  2. Check the log file mentioned in the follow-up message for the underlying bind failure.
  3. Verify nothing else occupies 127.0.0.1:<port> (or use the default ephemeral port 0).
  4. Check OS/firewall rules allowing listeners on loopback.

Example fix

// before (sandboxed tool)
impeccable serve-question payload.json
// after (run via the harness's network-enabled exec tool)
exec --network -- impeccable serve-question payload.json
Defensive patterns

Strategy: fallback

Validate before calling

// shell: confirm the tool can bind loopback before invoking
(exec 3<>/dev/tcp/127.0.0.1/0) 2>/dev/null && echo loopback-ok || echo sandboxed-no-network

Try / catch

// wrapper: detect exit 1 and 'failed to start' on stderr, then retry unsandboxed
try {
  run('impeccable serve-question --payload-path q.json');
} catch (e) {
  if (/failed to start/.test(e.stderr)) return runUnsandboxed(e.command);
  throw e;
}

Prevention

When it happens

Trigger: Running `serve-question` when the tiny_http server cannot bind/listen on 127.0.0.1 — typically because the exec is sandboxed without network permissions. The command then reads the log file and prints its tail before returning 1.

Common situations: Agent harnesses that sandbox commands with no network access; another process holding the port; firewall or OS restrictions on localhost binds.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


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