-
Notifications
You must be signed in to change notification settings - Fork 2.1k
[NemoClaw] spawnSync calls in onboard.js have no timeout — hung curl freezes entire onboarding wizard #1017
Description
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
- Run
nemoclaw onboard - 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)
- The wizard hangs indefinitely at the inference validation step
- No timeout, no error message — only Ctrl+C can recover
Environment
- Code review of
mainbranch (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 timeoutWhile 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