Skip to content

fix(core): inject NO_PROXY into waitForHttp loopback probes (#4181)#4215

Merged
cv merged 3 commits into
NVIDIA:mainfrom
latenighthackathon:fix/4181-waitforhttp-no-proxy
Jun 3, 2026
Merged

fix(core): inject NO_PROXY into waitForHttp loopback probes (#4181)#4215
cv merged 3 commits into
NVIDIA:mainfrom
latenighthackathon:fix/4181-waitforhttp-no-proxy

Conversation

@latenighthackathon

@latenighthackathon latenighthackathon commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

waitForHttp() in src/lib/core/wait.ts now spawns its curl probe with a loopback-safe environment so health checks for localhost / 127.0.0.1 services (Ollama, gateway, dashboard) bypass any user-configured HTTP_PROXY / http_proxy instead of tunneling loopback requests through the proxy and failing.

Problem

During nemoclaw onboard, selecting "Install Ollama (macOS)" installs Ollama via Homebrew and ollama serve becomes healthy on :11434, yet the wizard reports "Ollama did not become ready on :11434" and falls back to the provider menu. The provider menu then keeps offering "Install Ollama (macOS)" instead of "Local Ollama - running" on subsequent runs.

Root cause: waitForHttp() spawned curl with { stdio: "ignore" } and no env override, so the child curl inherited the ambient HTTP_PROXY / http_proxy. When that proxy does not bypass loopback (a common Privoxy setup on macOS), curl tunnels http://127.0.0.1:11434/ through the proxy, which returns 503, so the readiness probe fails for the entire deadline.

The codebase already documents this pattern in src/lib/onboard/http-proxy-preflight.ts ("NemoClaw injects NO_PROXY for its own subprocess spawns") and the withLocalNoProxy() helper in src/lib/subprocess-env.ts already implements it; waitForHttp() was the one subprocess spawn that was not going through that path.

A standalone repro confirms the mechanism: with http_proxy=http://203.0.113.1:9 curl -v --connect-timeout 1 --max-time 1 http://127.0.0.1:14999/, curl routes to 203.0.113.1:9; once NO_PROXY=localhost,127.0.0.1 is set, curl connects directly to the loopback target.

Related Issue

Closes #4181

Changes

  • waitForHttp() in src/lib/core/wait.ts now passes a curl-friendly env to its spawnSync so loopback probes (Ollama, gateway, dashboard) bypass any user HTTP_PROXY / http_proxy.
  • Adds a buildLoopbackProbeEnv() helper that reuses the existing withLocalNoProxy() helper in src/lib/subprocess-env.ts, so the set of bypassed hosts (localhost, 127.0.0.1, host.docker.internal, ::1, 0.0.0.0) stays consistent with every other NemoClaw subprocess.
  • waitForPort() uses nc and does not read HTTP_PROXY, so it is left unchanged.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Verification

  • npx prek run --all-files passes
  • npm test passes
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Ran: npx vitest run test/wait.test.ts (6/6 pass, including 3 new cases for buildLoopbackProbeEnv() covering the no-proxy, HTTP_PROXY-set, and pre-existing-NO_PROXY-entries paths); npx vitest run test/wait.test.ts src/lib/subprocess-env.test.ts test/credential-exposure.test.ts (23/23 pass, verifying no regression for the withLocalNoProxy consumers and the env-leak boundary); npx tsc --noEmit -p tsconfig.src.json clean.


Signed-off-by: latenighthackathon latenighthackathon@users.noreply.github.com

Summary by CodeRabbit

  • Bug Fixes

    • HTTP health checks now respect proxy environment settings and ensure loopback/local addresses bypass proxies.
  • Tests

    • Added regression tests that verify proxy environment variable handling, NO_PROXY/no_proxy updates for localhost entries, and restoration of prior environment state.

)

waitForHttp() spawns curl via spawnSync({ stdio: "ignore" }) with no env
override, so the child curl inherits HTTP_PROXY / http_proxy from the
user shell. When the user runs nemoclaw onboard behind Privoxy or a
corporate proxy that does not bypass loopback (a common macOS setup),
curl tunnels http://127.0.0.1:<port>/ through the proxy, which returns
503, and waitForHttp reports the service as unhealthy. Symptom on macOS:
"Install Ollama (macOS)" prompt instead of "Local Ollama -- running",
even though brew installed ollama and ollama serve is healthy on :11434.

Build the curl child env through the existing withLocalNoProxy() helper
(src/lib/subprocess-env.ts) so localhost, 127.0.0.1, host.docker.internal,
::1 and 0.0.0.0 are added to NO_PROXY / no_proxy whenever any HTTP_PROXY
is set. waitForPort() uses nc and does not need the fix.

Tests: 3 new cases on buildLoopbackProbeEnv covering the no-proxy,
HTTP_PROXY-set, and pre-existing-NO_PROXY-entries scenarios. 6 wait +
14 subprocess-env + 3 credential-exposure tests pass in the container.

Closes NVIDIA#4181.

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
@copy-pr-bot

copy-pr-bot Bot commented May 26, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 51c5190a-c30f-4796-b6c1-3ffc24f1ed95

📥 Commits

Reviewing files that changed from the base of the PR and between 699dd57 and eb048d5.

📒 Files selected for processing (1)
  • test/wait.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/wait.test.ts

📝 Walkthrough

Walkthrough

This PR fixes HTTP readiness checks failing when HTTP_PROXY is set by adding buildLoopbackProbeEnv() to inject NO_PROXY for localhost addresses, integrating it into waitForHttp() so curl bypasses proxies for local probes, and including comprehensive tests validating the environment behavior.

Changes

Loopback Proxy Environment Handling

Layer / File(s) Summary
Loopback probe environment builder
src/lib/core/wait.ts
New buildLoopbackProbeEnv() function copies process.env into a fresh object and applies withLocalNoProxy to ensure localhost and 127.0.0.1 are included in NO_PROXY/no_proxy for loopback-bound service probes.
HTTP readiness check integration
src/lib/core/wait.ts
waitForHttp() is updated to invoke buildLoopbackProbeEnv() and pass the result as the env option to spawnSync("curl", ...), so HTTP checks respect the proxy-adjusted environment.
Regression test coverage
test/wait.test.ts
Test imports updated to include buildLoopbackProbeEnv and afterEach. New regression tests snapshot and clear proxy env, verify localhost entries are injected into NO_PROXY/no_proxy when proxy variables exist, and confirm pre-existing NO_PROXY values are preserved.

Sequence Diagram

sequenceDiagram
  participant waitForHttp
  participant buildLoopbackProbeEnv
  participant curl
  participant localhost_service
  waitForHttp->>buildLoopbackProbeEnv: request adjusted env (with NO_PROXY)
  buildLoopbackProbeEnv-->>waitForHttp: return env {NO_PROXY: "localhost,127.0.0.1,..."}
  waitForHttp->>curl: spawnSync("curl", ..., env=adjustedEnv)
  curl->>localhost_service: direct HTTP request (proxy bypassed)
  localhost_service-->>curl: 200 OK
  curl-->>waitForHttp: exit status 0
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 When proxies try to lead probes astray,
I tuck localhost safely out of the way.
With NO_PROXY stitched into the child env door,
Curl finds 127.0.0.1 and knocks once more.
Now readiness checks hop home, as they did before.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the main change: injecting NO_PROXY into waitForHttp loopback probes to fix a core readiness check issue.
Linked Issues check ✅ Passed The code changes fully address issue #4181 by implementing the buildLoopbackProbeEnv() helper and updating waitForHttp() to inject NO_PROXY into curl's environment for localhost probes.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the NO_PROXY injection issue: buildLoopbackProbeEnv() export, waitForHttp() env parameter addition, and comprehensive tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for submitting this detailed PR about fixing the Ollama readiness check issue on macOS. This proposes a way to inject NO_PROXY into waitForHttp loopback probes, ensuring that curl bypasses the user's HTTP_PROXY for localhost probes, which should resolve the issue where the wizard reports Ollama as not ready and falls back to the provider menu.


Related open issues:

@wscurran wscurran added area: networking DNS, proxy, TLS, ports, host aliases, or connectivity bug-fix PR fixes a bug or regression and removed fix labels Jun 3, 2026
@cv cv added the v0.0.58 Release target label Jun 3, 2026
Comment thread test/wait.test.ts Fixed
@cv cv merged commit 3033bd1 into NVIDIA:main Jun 3, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: networking DNS, proxy, TLS, ports, host aliases, or connectivity bug-fix PR fixes a bug or regression platform: macos Affects macOS, including Apple Silicon v0.0.58 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[macOS][Onboard] Ollama readiness check fails when HTTP_PROXY is set — waitForHttp does not inject NO_PROXY for localhost probes

4 participants