Skip to content

feat: verify Headroom proxy health before launching claude#48

Merged
smartwatermelon merged 1 commit into
mainfrom
claude/proxy-health-check-89077
Apr 30, 2026
Merged

feat: verify Headroom proxy health before launching claude#48
smartwatermelon merged 1 commit into
mainfrom
claude/proxy-health-check-89077

Conversation

@smartwatermelon
Copy link
Copy Markdown
Owner

Summary

  • Adds lib/proxy-health.sh::check_proxy_health() — a pre-launch check that pings ${ANTHROPIC_BASE_URL}/health (1s timeout) when the URL points at localhost or 127.0.0.1. On failure (refused, timeout, HTTP 4xx/5xx), the wrapper unsets ANTHROPIC_BASE_URL and warns the user that the session will fall back to talking to Anthropic directly.
  • Wired into bin/claude-wrapper after secrets/pre-launch logic, before exec. Function always return 0 so it cannot abort the wrapper under set -e.
  • Skips silently for unset URLs, non-localhost overrides, and missing curl.

Why

~/.config/bash/services.sh exports ANTHROPIC_BASE_URL=http://localhost:8787 based on a port-bound check (lsof). That doesn't catch a wedged or dead Headroom process holding the port — every Claude request would then hang or fail. This check verifies the proxy actually responds before we hand control to claude.

Test plan

  • New tests/test-proxy-health.sh — 15 tests covering: unset URL, remote URL (skip), healthy proxy, refused connection (exit 7), HTTP error (exit 22), 127.0.0.1 form, missing curl (graceful), set -e safety, trailing-slash URL handling. All 15 pass.
  • Existing test suites still green (test-wrapper.sh 59/59, test-remote-session.sh 26/26).
  • shellcheck --severity=warning --exclude=SC2312 --external-sources clean on all changed files.
  • Live smoke test: CLAUDE_DEBUG=true claude-wrapper --version with proxy alive → DEBUG: Headroom proxy healthy at http://localhost:8787.
  • Live failure path: ANTHROPIC_BASE_URL=http://localhost:9999 CLAUDE_DEBUG=true claude-wrapper --versionWARNING: Headroom proxy at http://localhost:9999 is not responding ... then exec proceeds without the env var.
  • Local pre-commit reviewers (code-reviewer + adversarial-reviewer): PASS
  • Pre-push reviewers (full-diff + codebase): PASS
  • CI green

🤖 Generated with Claude Code

Adds a pre-launch health check that pings the Headroom proxy at
ANTHROPIC_BASE_URL/health when the URL points at localhost or 127.0.0.1.
If curl --fail does not return 200 within 1 second, unset
ANTHROPIC_BASE_URL and warn the user that the session will talk to
Anthropic directly. This catches the case where shell startup bound the
env var because the port was occupied (lsof) but the process behind it
is wedged or dead.

The check is implemented in lib/proxy-health.sh as a standalone module,
sourced from bin/claude-wrapper and called unconditionally before exec
(it operates on the wrapper's own env, not project secrets). The
function always returns 0 so it cannot abort the wrapper under set -e.

Skips silently for unset URLs, non-localhost URLs (user override), and
when curl is not installed.

Tests in tests/test-proxy-health.sh cover all decision branches plus
the set -e safety property.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@claude
Copy link
Copy Markdown

claude Bot commented Apr 30, 2026

No blocking issues found.

The wrapper restructuring correctly moves exec to be unconditional (outside both if secrets_available branches), equivalent to the original where both branches called exec. check_proxy_health always returns 0, never aborts the wrapper, and the unset ANTHROPIC_BASE_URL correctly propagates to the exec'd child via inherited environment. The localhost regex is well-formed and not susceptible to prefix collisions (e.g. localhostevil.com). The trailing-slash strip on the health URL is correct.

VERDICT: PASS

@smartwatermelon smartwatermelon merged commit 8d7015f into main Apr 30, 2026
4 checks passed
@smartwatermelon smartwatermelon deleted the claude/proxy-health-check-89077 branch April 30, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant