Skip to content

fix(gateway): keep probe routes reachable with root-mounted control ui#38199

Merged
vincentkoc merged 3 commits intomainfrom
vincentkoc-code/18446-root-ui-probe-fix
Mar 6, 2026
Merged

fix(gateway): keep probe routes reachable with root-mounted control ui#38199
vincentkoc merged 3 commits intomainfrom
vincentkoc-code/18446-root-ui-probe-fix

Conversation

@vincentkoc
Copy link
Copy Markdown
Member

Summary

  • Problem: when the Control UI is mounted at /, the SPA request classifier can still claim /health, /healthz, /ready, and /readyz before the gateway probe handler runs.
  • Why it matters: deployment probes can receive Control UI fallback responses instead of the machine probe payload, which keeps [Bug]: /health and /healthz can return Control UI HTML 200 instead of machine health payload #18446 reproducible even after Gateway: add healthz/readyz probe endpoints for container checks #31272 landed.
  • What changed: root-mounted Control UI classification now explicitly leaves the four probe routes outside the SPA catch-all, and regression tests cover both probe reachability and plugin precedence on probe paths.
  • What did NOT change (scope boundary): no deep readiness semantics, no auth model changes, and no route-order reversal that would shadow plugin-owned probe paths.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22
  • Model/provider: N/A
  • Integration/channel (if any): gateway HTTP server
  • Relevant config (redacted): root-mounted Control UI (gateway.controlUi.basePath = "/" equivalent normalization to empty base path)

Steps

  1. Start the gateway with Control UI mounted at /.
  2. Request /healthz and /readyz.
  3. Mount a plugin handler on /healthz and request it again.

Expected

  • Probe paths return the gateway probe JSON when unclaimed.
  • Plugin handlers on probe paths still win when explicitly registered.

Actual

  • Matches expected.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • Root-mounted Control UI no longer swallows /health, /healthz, /ready, or /readyz.
    • Plugin handlers mounted on /healthz still keep precedence.
  • Edge cases checked:
    • Existing non-probe root-mounted Control UI fallthrough behavior remains intact.
  • What you did not verify:
    • Full end-to-end deploy on Render/Kubernetes in this PR.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert the two commits in this PR.
  • Files/config to restore:
    • src/gateway/control-ui-routing.ts
    • src/gateway/server.plugin-http-auth.test.ts
    • CHANGELOG.md
  • Known bad symptoms reviewers should watch for:
    • Root-mounted Control UI starts serving probe paths again.
    • Plugin routes mounted on /healthz stop taking precedence.

Risks and Mitigations

  • Risk: root-mounted Control UI path classification grows another special-case allowlist.
    • Mitigation: keep the allowlist limited to the four built-in probe paths and cover it with regression tests.

@vincentkoc vincentkoc force-pushed the vincentkoc-code/18446-root-ui-probe-fix branch from 0508603 to b6b1948 Compare March 6, 2026 17:10
@vincentkoc vincentkoc marked this pull request as ready for review March 6, 2026 17:13
@vincentkoc vincentkoc merged commit d070c44 into main Mar 6, 2026
7 checks passed
@vincentkoc vincentkoc deleted the vincentkoc-code/18446-root-ui-probe-fix branch March 6, 2026 17:13
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 6, 2026

Greptile Summary

This PR fixes a routing bug where the Control UI's SPA catch-all, when mounted at /, could intercept /health, /healthz, /ready, and /readyz before the gateway probe handler could respond.

The fix:

  • Adds ROOT_MOUNTED_GATEWAY_PROBE_PATHS constant in control-ui-routing.ts (line 9)
  • Inserts a guard before the SPA fallback (lines 24–26) that returns not-control-ui for the four probe paths when basePath is empty
  • Placement correctly handles all HTTP methods

Test coverage:

  • Integration tests verify probe reachability and plugin override on probe paths when Control UI is root-mounted
  • No regression in existing behavior

Scope boundaries respected: No changes to readiness semantics, auth model, or route ordering.

Confidence Score: 5/5

  • This PR is safe to merge — the fix is minimal, correctly scoped, and thoroughly tested at the integration level.
  • The change is a single targeted guard inserted at the correct point in the routing decision tree. The logic is straightforward (Set lookup before SPA fallback). Integration tests comprehensively verify both the primary fix (probe reachability when Control UI is root-mounted) and backward compatibility (plugin handlers still take precedence on probe paths). No existing tests were removed or weakened. The placement correctly handles all HTTP methods.
  • No files require special attention.

Last reviewed commit: 57a2661

Saitop pushed a commit to NomiciAI/openclaw that referenced this pull request Mar 8, 2026
openclaw#38199)

* fix(gateway): keep probe routes reachable with root-mounted control ui

* Changelog: add root-mounted probe precedence fix entry

* Update CHANGELOG.md
jenawant pushed a commit to jenawant/openclaw that referenced this pull request Mar 10, 2026
openclaw#38199)

* fix(gateway): keep probe routes reachable with root-mounted control ui

* Changelog: add root-mounted probe precedence fix entry

* Update CHANGELOG.md
dhoman pushed a commit to dhoman/chrono-claw that referenced this pull request Mar 11, 2026
openclaw#38199)

* fix(gateway): keep probe routes reachable with root-mounted control ui

* Changelog: add root-mounted probe precedence fix entry

* Update CHANGELOG.md
senw-developers pushed a commit to senw-developers/va-openclaw that referenced this pull request Mar 17, 2026
openclaw#38199)

* fix(gateway): keep probe routes reachable with root-mounted control ui

* Changelog: add root-mounted probe precedence fix entry

* Update CHANGELOG.md
V-Gutierrez pushed a commit to V-Gutierrez/openclaw-vendor that referenced this pull request Mar 17, 2026
openclaw#38199)

* fix(gateway): keep probe routes reachable with root-mounted control ui

* Changelog: add root-mounted probe precedence fix entry

* Update CHANGELOG.md
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
openclaw#38199)

* fix(gateway): keep probe routes reachable with root-mounted control ui

* Changelog: add root-mounted probe precedence fix entry

* Update CHANGELOG.md
(cherry picked from commit d070c44)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
openclaw#38199)

* fix(gateway): keep probe routes reachable with root-mounted control ui

* Changelog: add root-mounted probe precedence fix entry

* Update CHANGELOG.md
(cherry picked from commit d070c44)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
openclaw#38199)

* fix(gateway): keep probe routes reachable with root-mounted control ui

* Changelog: add root-mounted probe precedence fix entry

* Update CHANGELOG.md
(cherry picked from commit d070c44)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: /health and /healthz can return Control UI HTML 200 instead of machine health payload

1 participant