Skip to content

[NemoClaw] spawnSync calls in onboard.js have no timeout — hung curl freezes entire onboarding wizard #1017

@latenighthackathon

Description

@latenighthackathon

Description

In bin/lib/onboard.js, all inference provider validation calls use spawnSync("bash", ["-c", cmd]) with no timeout property. Node.js spawnSync supports a timeout option that kills the child process after a deadline, but it is not used anywhere in the file.

If a curl request hangs (DNS stall, unresponsive endpoint, network timeout beyond curl's --max-time), the entire onboarding wizard freezes indefinitely with no way to recover other than killing the process.

What happens: The onboard wizard hangs with no output, no spinner, no timeout. User must Ctrl+C and restart.

What should happen: spawnSync calls should include a timeout (e.g., 30000ms) to prevent indefinite hangs.

Reproduction Steps

  1. Run nemoclaw onboard
  2. Select a custom OpenAI-compatible endpoint and provide a URL that accepts TCP connections but never responds (e.g., a server that accepts the socket but sends no data)
  3. The wizard hangs indefinitely at the inference validation step
  4. No timeout, no error message — only Ctrl+C can recover

Environment

  • Code review of main branch (commit HEAD as of 2026-03-26)
  • Affected file: bin/lib/onboard.js

Logs

All affected call sites — none have a timeout property:

// Line 597 — OpenAI-compatible probe
const result = spawnSync("bash", ["-c", cmd], {
  cwd: ROOT,
  encoding: "utf8",
  env: { ...process.env, NEMOCLAW_PROBE_API_KEY: apiKey },
  // NO timeout
});

// Line 646 — Anthropic probe
const result = spawnSync("bash", ["-c", cmd], {
  cwd: ROOT,
  encoding: "utf8",
  env: { ...process.env, NEMOCLAW_PROBE_API_KEY: apiKey },
  // NO timeout
});

// Line 786 — NVIDIA endpoint model list
const result = spawnSync("bash", ["-c", cmd], {
  cwd: ROOT,
  encoding: "utf8",
  env: { ...process.env, NEMOCLAW_PROBE_API_KEY: apiKey },
  // NO timeout
});

// Line 839 — OpenAI-like model list
const result = spawnSync("bash", ["-c", cmd], { ... });  // NO timeout

// Line 876 — Anthropic model list
const result = spawnSync("bash", ["-c", cmd], { ... });  // NO timeout

// Line 1049 — ollama pull
const result = spawnSync("bash", ["-c", `ollama pull ${shellQuote(model)}`], { ... });  // NO timeout

// Line 1103 — OpenShell install
const result = spawnSync("bash", [...], { ... });  // NO timeout

While getCurlTimingArgs() (line 378) returns --connect-timeout 5 --max-time 20, this only limits curl itself. If bash or the shell layer hangs before or after curl, spawnSync blocks forever.

Fix — add timeout to all spawnSync calls:

const result = spawnSync("bash", ["-c", cmd], {
  cwd: ROOT,
  encoding: "utf8",
  timeout: 30000,  // 30 seconds
  env: { ...process.env, NEMOCLAW_PROBE_API_KEY: apiKey },
});

Checklist

  • I confirmed this bug is reproducible
  • I searched existing issues and this is not a duplicate

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancement: testingUse this label to identify requests to improve NemoClaw test coverage.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions