[Brev][Onboard] Hermes onboard web UI shows a red error card with RETRY for sandbox image build steps that succeeded
- Dominant language
- TypeScript
- Stars
- 22.5k
- Forks
- 3.1k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 715
Description
## Description
The NemoClaw onboarding web UI served by `nemoclaw-onboard-ui.service` on a Brev launchable renders a red error card with a **RETRY** button under the "Create sandbox" step while onboarding the Hermes Agent, quoting sandbox image build step `#47 [stage-6 5/48] RUN ... /usr/local/bin/hermes --version`.
That build step actually succeeds (`#47 DONE 0.5s`). The image build runs to completion, the sandbox reaches `Phase: Ready`, and onboarding finishes all 8 phases with `Hermes is ready`. The UI never retracts or supersedes the error card, so the operator is shown a failure for a successful onboarding and is invited to click RETRY, which re-runs `brev-quickstart` and rebuilds the entire sandbox for no reason.
The Hermes agent Dockerfile is affected far more widely than other agents: **13 distinct build steps** of `stage-6` contain the literal word `ERROR` in guard text that never fires (see Actual Result), and every one of them reported `DONE`.
Reproduced with agent Hermes Agent v0.18.0 on the OpenRouter provider.
- **Platform scope:** Reproduced on Brev launchable (Ubuntu 22.04) only; other platforms not tested
- **Regression:** Unknown — earlier versions not tested
## Environment
```text
Device: Brev launchable instance (n2d-standard-4, CPU-only, no GPU)
OS: Ubuntu 22.04.5 LTS (Linux 6.8.0-1064-gcp)
Architecture: x86_64
Node.js: v22.23.2
npm: 10.9.8
Docker: Docker version 29.1.3, build 29.1.3-0ubuntu3~22.04.2
OpenShell CLI: openshell 0.0.85
NemoClaw: nemoclaw v0.0.97
OpenClaw: N/A - agent is Hermes Agent v0.18.0 (no openclaw binary in the Hermes sandbox)
```
## Steps to Reproduce
1. Create a Brev instance from the NemoClaw launchable and open the onboarding web UI (port 3000) in a browser.
2. Select agent **Hermes Agent**, provider **OpenRouter**, model `nvidia/nemotron-3-ultra-550b-a55b:free`, sandbox name `brev-hermes`.
3. Start onboarding and watch the "Create sandbox" step and the Activity Log.
4. When the image build reaches `#47 [stage-6 5/48] RUN ... hermes --version`, observe the step status in the UI.
5. Let onboarding run to completion, then on the host run:
```bash
nemoclaw list
nemoclaw brev-hermes status
```
## Expected Result
BuildKit progress lines are rendered as build progress. The UI reports an error only when a build step actually fails (BuildKit prints its own `ERROR: process "..." did not complete successfully`) or when `brev-quickstart` exits non-zero. A step that reports `DONE` is shown as complete, and a successful onboarding ends in the success state with no RETRY offered.
## Actual Result
A red error card with a RETRY button appears under "Create sandbox" quoting:
```text
#47 [stage-6 5/48] RUN set -eu; hermes_path="$(command -v hermes 2>/dev/null || true)"; if [ "$hermes_path" != "/usr/local/bin/hermes" ]; then echo "ERROR: expected hermes at /usr/local/bin/hermes, got ${hermes_path:-missing}" >&2; exit 1; fi; test -x /usr/local/bin/hermes; /usr/local/bin/hermes --version
```
The card stays on screen while the build continues past that step and onboarding completes successfully:
```text
#47 DONE 0.5s
nemoclaw brev-hermes status -> Phase: Ready, Harness: Hermes Agent
(gateway), Agent: Hermes Agent v0.18.0,
Inference reachable
onboard log -> "Hermes is ready"
```
13 distinct `stage-6` build steps carry guard text containing the word `ERROR`, and all of them reported `DONE`:
```text
#47 [stage-6 5/48] ... ERROR: expected hermes at ...
#50 [stage-6 8/48] ... ERROR: Hermes dashboard at ...
#51 [stage-6 9/48] ... ERROR: make survived runtime purge
#60 [stage-6 18/48] ... ERROR: validate ...
#63 [stage-6 21/48] ... ERROR: patch ...
#65 [stage-6 23/48] ... ERROR: validate ...
#66 [stage-6 24/48] ... ERROR: finalize ...
#68 [stage-6 26/48] ... ERROR: ...
#69 [stage-6 27/48] ... ERROR: installed Hermes ...
#70 [stage-6 28/48] ... ERROR: ...
#71 [stage-6 29/48] ... ERROR: ...
#83 [stage-6 41/48] ... ERROR: ...
#89 [stage-6 47/48] ... ERROR: ...
```
## Analysis
Three behaviours combine:
1. BuildKit writes its progress lines — `#NN [stage-6 x/48] RUN {entire command text}` — to **stderr**, not stdout.
2. `onboard-ui/lib/services/nemoclaw.ts`, `parseOnboardStderr()`, emits a hard `{type:"error"}` event for any stderr line matching:
```text
/\b(error|failed|unauthorized|forbidden|authentication|invalid (?:api )?key|upstream unavailable)\b/i
```
There is no exclusion for BuildKit progress lines and no notion of whether the step later reported `DONE`.
3. `agents/hermes/Dockerfile` contains sanity guards that never fire but whose message text starts with the literal word `ERROR`, for example `echo "ERROR: expected hermes at /usr/local/bin/hermes, got ..."`. BuildKit echoes the whole RUN body, so the word `ERROR` appears in a line that then reports `DONE`. Unlike other agents, the Hermes Dockerfile trips this on 13 separate build steps.
So the UI reacts to the *source text* of a guard rather than to the guard firing.
Note the stdout path does not have this problem: `parseOnboardLine()`'s fallback uses a case-sensitive check for `"Error:"`, which does not match `"ERROR:"`. Only the stderr regex is case-insensitive.
**Suggested fix:** in `parseOnboardStderr()`, skip BuildKit progress lines (`/^#\d+\s/`), or only raise an error on BuildKit's own `ERROR: process "..." did not complete successfully` marker and on a non-zero child exit code. Fixing the parser covers every agent at once; rewording the Dockerfile guard text would be a per-agent workaround.
## Related Bugs / not duplicate of
Issue #8101 reports the same UI symptom for the LangChain Deep Agents Code (`dcode`) agent, where the guard text lives in `agents/langchain-deepagents-code/Dockerfile` and only 2 build steps are affected.
This report is filed separately at the reporter's request to cover the Hermes agent path: a different Dockerfile, a different build stage (`stage-6` of 48 rather than `stage-1` of 34), and a much wider blast radius (13 affected steps rather than 2). If the fix is applied in `parseOnboardStderr()` as suggested above, both are resolved together and this can be closed alongside #8101.
## Logs
Onboarding UI service log (host names removed), showing the flagged step and the successful continuation of the same build:
```text
[onboard] #46 DONE 0.6s
[onboard] #47 [stage-6 5/48] RUN set -eu; hermes_path="$(command -v hermes 2>/dev/null || true)"; ... /usr/local/bin/hermes --version
[onboard] #47 DONE 0.5s
[onboard] #48 DONE 0.7s
[onboard] #49 DONE 9.4s
[onboard] #69 [stage-6 27/48] RUN hermes_version_output="$(/usr/local/bin/hermes --version)" ...
[onboard] #72 [stage-6 30/48] RUN mv /usr/local/bin/hermes /usr/local/bin/hermes.real && install -m 075...
[onboard] #91 exporting to image
[onboard] * Sandbox 'brev-hermes' created
[onboard] [7/8] Setting up Hermes Agent inside sandbox
[onboard] [8/8] Policy presets
[onboard] Applied preset: npm
[onboard] Applied preset: huggingface
[onboard] Applied preset: brew
[onboard] Hermes is ready
```
Anyone who plans to fix one of #8101, #8105 and #8109 should consider to fix them altogether.
Contributor guide
Research direction
Read onboard-ui/lib/services/nemoclaw.ts, starting with parseOnboardStderr(), and compare its stderr matching with the logged BuildKit progress lines. Reproduce the onboarding flow or inspect the provided logs, then verify that successful DONE steps no longer produce a red error card or RETRY while genuine build failures still do.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100