Skip to content

install.sh: smoke test never times out, and interrupting it reports "installation failed" #3017

Description

@Gael-BB

Summary

scripts/install.sh offers a post-install smoke test described as "starts unitree-go2 for 60s", but the command is never wrapped in a timeout — it runs indefinitely. The only way out is Ctrl+C, and the resulting signal exit code is then misreported as installation failed, pointing users at this issue tracker even though the install succeeded.

Two separate bugs, one user-visible symptom.

Bug 1: the 60s timeout doesn't exist

install.sh:871 prompts:

Run a quick smoke test? (starts unitree-go2 for 60s)

and install.sh:897 checks for exit code 124 — the code timeout(1) returns when it kills a command:

if [[ $exit_code -eq 124 ]]; then ok "smoke test: ran 60s without crash ✓"

But the launch at install.sh:890 has no timeout wrapper:

local exit_code=0
pushd "$dir" >/dev/null
source "$venv"
$cmd &                      # <-- no `timeout 60`
local pid=$!
wait $pid || exit_code=$?

grep -n 'timeout' scripts/install.sh returns no hits outside unrelated rpc_timeout config keys. The process runs until the user kills it, and the 124 branch is unreachable.

Bug 2: interrupting it reports a failed install

Killing the smoke test is the only way to end it, but the exit-code handling doesn't cover all the signals that can result.

install.sh:898 accepts 130 (SIGINT) and 137 (SIGKILL) as user-initiated, and the cleanup EXIT trap at install.sh:939 exempts only 130:

[[ $ec -ne 0 ]] && [[ $ec -ne 130 ]] && { printf "\n"; err "installation failed (exit ${ec})"; err "help: https://github.com/dimensionalOS/dimos/issues"; }

In my run, Ctrl+C during the MuJoCo sim produced exit 129 (SIGHUP, 128+1) rather than 130, which falls through every branch and trips the generic failure handler. I haven't isolated why the interrupt surfaces as SIGHUP rather than SIGINT — possibly related to how the native rerun viewer tears down relative to the process group — so treat that specific code as one instance rather than the whole story. The general point stands regardless: a signal-terminated smoke test shouldn't be reported as a failed installation, and 130/137 aren't the only codes reachable.

Because run_post_install_tests is the second-to-last call in main(), the script dies before print_quickstart — so the user loses the activation instructions and never learns dimos is in the venv rather than on $PATH. The install is complete and working, but it looks broken and the quickstart is silently swallowed.

Reproduction

  1. Run the curl installer on macOS with the sim extras.
  2. Accept the smoke test.
  3. Observe it run well past 60s (mine ran ~8 minutes in the rerun viewer).
  4. Ctrl+C.
  5. ✗ installation failed (exit 129) + this issue tracker link.

The install itself is fine: .venv/bin/dimos --help works, and ~/.local/state/dimos/runs/ has a clean run record for the smoke test.

Note on fixing: macOS has no timeout

The obvious fix — wrapping line 890 in timeout 60 — will not work on macOS. timeout is GNU coreutils and isn't present in a stock install:

$ which timeout gtimeout
timeout not found
gtimeout not found

So a portable fix needs either a coreutils dependency (gtimeout, which the script would have to detect) or a shell-native watchdog, roughly:

$cmd &
local pid=$!
( sleep 60; kill -INT "$pid" 2>/dev/null ) &
local watchdog=$!
wait "$pid" || exit_code=$?
kill "$watchdog" 2>/dev/null

That also makes the timeout path deliver SIGINT deliberately, rather than depending on which signal happens to reach the process.

Separately, the cleanup trap probably shouldn't treat a smoke-test signal exit as an install failure at all — the smoke test runs after do_install/verify_install have already succeeded.

Environment

OS macOS 26.5.2 (arm64)
bash 3.2.57(1)-release
dimos main @ 29f35555
Extras sim (MuJoCo), unitree

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions