Skip to content

fix(gateway): let non-GET requests fall through controlUi routing when basePath is set#32311

Merged
steipete merged 2 commits intoopenclaw:mainfrom
ademczuk:fix/controlui-webhook-405
Mar 3, 2026
Merged

fix(gateway): let non-GET requests fall through controlUi routing when basePath is set#32311
steipete merged 2 commits intoopenclaw:mainfrom
ademczuk:fix/controlui-webhook-405

Conversation

@ademczuk
Copy link
Contributor

@ademczuk ademczuk commented Mar 2, 2026

Summary

Test plan

  • pnpm vitest run src/gateway/control-ui-routing.test.ts — 6 tests pass (updated + new)
  • pnpm vitest run src/gateway/control-ui.http.test.ts — 18 tests pass (updated)
  • pnpm vitest run src/gateway/gateway-misc.test.ts — 21 tests pass (regression)
  • pnpm tsgo — zero errors
  • pnpm check — passes (no format issues in changed files)

🤖 Generated with Claude Code

@openclaw-barnacle openclaw-barnacle bot added app: web-ui App: web-ui gateway Gateway runtime size: XS labels Mar 2, 2026
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 2, 2026

Greptile Summary

This PR fixes a 2026.3.1 regression where all POST (and other non-GET/HEAD) requests returned HTTP 405 when controlUiBasePath was configured, breaking plugin webhook handlers (BlueBubbles, Mattermost, etc.).

Root cause: classifyControlUiRequest was returning { kind: "method-not-allowed" } for non-read methods under a configured basePath, causing handleControlUiHttpRequest to consume and reject the request before plugin handlers could see it.

Fix: The one-line change at control-ui-routing.ts:38 returns { kind: "not-control-ui" } instead, exactly matching the existing no-basePath branch (line 28–30). This lets the request fall through to downstream plugin HTTP handlers unchanged.

Cleanup: The now-dead method-not-allowed union variant, its handler branch in control-ui.ts, and the respondMethodNotAllowed helper are all removed, leaving no orphaned code paths.

Test coverage: Existing tests are updated and a new parameterised test covers PUT/DELETE/PATCH/OPTIONS under basePath; the integration test confirms handled === false and no response is written for POST requests.

Confidence Score: 5/5

  • This PR is safe to merge — it is a minimal, targeted regression fix with no logic concerns.
  • The change is a single-line fix that makes basePath behaviour consistent with the already-correct no-basePath behaviour. Dead code is cleanly removed, all affected code paths are exercised by the updated and new tests, and there are no security implications introduced by letting non-GET/HEAD requests fall through (the control UI SPA only needs GET/HEAD; plugin handlers were already the intended owners of POST/PUT/DELETE routes).
  • No files require special attention.

Last reviewed commit: 2474cb6

ademczuk and others added 2 commits March 3, 2026 00:10
…n basePath is set

When controlUiBasePath is set, classifyControlUiRequest returned
method-not-allowed (405) for all non-GET/HEAD requests under basePath,
blocking plugin webhook handlers (BlueBubbles, Mattermost, etc.) from
receiving POST requests. This is a 2026.3.1 regression.

Return not-control-ui instead, matching the empty-basePath behavior, so
requests fall through to plugin HTTP handlers. Remove the now-dead
method-not-allowed type variant, handler branch, and utility function.

Closes openclaw#31983
Closes openclaw#32275

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@steipete steipete force-pushed the fix/controlui-webhook-405 branch from 2474cb6 to 9541f36 Compare March 3, 2026 00:11
@steipete steipete merged commit e870cee into openclaw:main Mar 3, 2026
@steipete
Copy link
Contributor

steipete commented Mar 3, 2026

Landed via temp rebase onto main.

  • Gate:

openclaw@2026.3.2 check /Users/steipete/Projects/clawdbot2
pnpm format:check && pnpm tsgo && pnpm lint && pnpm lint:tmp:no-random-messaging && pnpm lint:tmp:channel-agnostic-boundaries && pnpm lint:tmp:no-raw-channel-fetch && pnpm lint:agent:ingress-owner && pnpm lint:plugins:no-register-http-handler && pnpm lint:webhook:no-low-level-body-read && pnpm lint:auth:no-pairing-store-group && pnpm lint:auth:pairing-account-scope && pnpm check:host-env-policy:swift

openclaw@2026.3.2 format:check /Users/steipete/Projects/clawdbot2
oxfmt --check

Checking formatting...

All matched files use the correct format.
Finished in 1584ms on 6117 files using 16 threads.

openclaw@2026.3.2 lint /Users/steipete/Projects/clawdbot2
oxlint --type-aware

Found 0 warnings and 0 errors.
Finished in 2.5s on 4485 files with 136 rules using 16 threads.

openclaw@2026.3.2 lint:tmp:no-random-messaging /Users/steipete/Projects/clawdbot2
node scripts/check-no-random-messaging-tmp.mjs

openclaw@2026.3.2 lint:tmp:channel-agnostic-boundaries /Users/steipete/Projects/clawdbot2
node scripts/check-channel-agnostic-boundaries.mjs

openclaw@2026.3.2 lint:tmp:no-raw-channel-fetch /Users/steipete/Projects/clawdbot2
node scripts/check-no-raw-channel-fetch.mjs

openclaw@2026.3.2 lint:agent:ingress-owner /Users/steipete/Projects/clawdbot2
node scripts/check-ingress-agent-owner-context.mjs

openclaw@2026.3.2 lint:plugins:no-register-http-handler /Users/steipete/Projects/clawdbot2
node scripts/check-no-register-http-handler.mjs

openclaw@2026.3.2 lint:webhook:no-low-level-body-read /Users/steipete/Projects/clawdbot2
node scripts/check-webhook-auth-body-order.mjs

openclaw@2026.3.2 lint:auth:no-pairing-store-group /Users/steipete/Projects/clawdbot2
node scripts/check-no-pairing-store-group-auth.mjs

openclaw@2026.3.2 lint:auth:pairing-account-scope /Users/steipete/Projects/clawdbot2
node scripts/check-pairing-account-scope.mjs

openclaw@2026.3.2 check:host-env-policy:swift /Users/steipete/Projects/clawdbot2
node scripts/generate-host-env-security-policy-swift.mjs --check

OK apps/macos/Sources/OpenClaw/HostEnvSecurityPolicy.generated.swift

openclaw@2026.3.2 test /Users/steipete/Projects/clawdbot2
node scripts/test-parallel.mjs -- src/gateway/control-ui-routing.test.ts src/gateway/control-ui.http.test.ts

RUN v4.0.18 /Users/steipete/Projects/clawdbot2

✓ src/gateway/control-ui-routing.test.ts (6 tests) 2ms
✓ src/gateway/control-ui.http.test.ts (18 tests) 24ms

Test Files 2 passed (2)
Tests 24 passed (24)
Start at 00:23:44
Duration 316ms (transform 262ms, setup 234ms, import 102ms, tests 26ms, environment 0ms)

Thanks @ademczuk!

@ademczuk ademczuk deleted the fix/controlui-webhook-405 branch March 3, 2026 07:45
dawi369 pushed a commit to dawi369/davis that referenced this pull request Mar 3, 2026
OWALabuy pushed a commit to kcinzgg/openclaw that referenced this pull request Mar 4, 2026
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui gateway Gateway runtime size: XS

Projects

None yet

2 participants