Skip to content

fix(gateway): return 404 for missing static assets instead of SPA fallback#12060

Merged
mbelinky merged 1 commit intoopenclaw:mainfrom
mcaxtr:fix/11556-webchat-favicon-static
Feb 20, 2026
Merged

fix(gateway): return 404 for missing static assets instead of SPA fallback#12060
mbelinky merged 1 commit intoopenclaw:mainfrom
mcaxtr:fix/11556-webchat-favicon-static

Conversation

@mcaxtr
Copy link
Contributor

@mcaxtr mcaxtr commented Feb 8, 2026

Fixes #11556

Summary

The webchat SPA catch-all route in handleControlUiHttpRequest() serves index.html for all unmatched paths — including requests for static assets like /webchat/favicon.svg. This causes the logo to appear broken in the webchat UI because the browser receives HTML (with Content-Type: text/html) instead of the actual SVG file.

Root Cause

In src/gateway/control-ui.ts, the SPA fallback (lines 355-364) fires whenever a requested file doesn't exist on disk. It doesn't distinguish between:

  • Navigation requests (extensionless paths like /webchat/chat) → should get index.html for client-side routing
  • Asset requests (paths with file extensions like /webchat/favicon.svg) → should get 404 if the file is missing

Fix

Before the SPA fallback, check path.extname(fileRel). If the requested path has a file extension and the file doesn't exist, return 404 instead of serving index.html. Extensionless paths continue to get the SPA fallback as before.

Test Plan

  • New test: missing static asset path (/webchat/favicon.svg) returns 404
  • New test: extensionless SPA path (/webchat/chat) still gets index.html fallback (200)
  • Existing test: security headers still applied
  • All 2 new tests fail before fix, pass after (TDD)
  • Full suite: 251 tests pass, 0 failures
  • pnpm build passes
  • pnpm check passes (lint + format)

Greptile Overview

Greptile Summary

Changes tighten the Control UI (webchat SPA) fallback behavior so that requests for missing static assets (e.g. .svg, .js, .css, etc.) return 404 Not Found instead of incorrectly serving index.html. This prevents browsers from receiving HTML for asset URLs (fixing broken favicon/logo scenarios) while preserving SPA routing for extensionless routes and dotted path segments.

Implementation-wise, src/gateway/control-ui.ts introduces a STATIC_ASSET_EXTENSIONS allowlist and checks it after the on-disk file lookup but before the SPA index.html fallback. Tests in src/gateway/control-ui.test.ts cover missing-asset 404s (GET/HEAD), extensionless SPA fallback, dotted-route fallback, and .html-suffixed route fallback.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk.
  • The change is narrowly scoped (a single allowlist check before SPA fallback) and is covered by targeted tests for the previously broken behavior (missing assets returning index.html) plus regressions (dotted SPA routes and .html routes). No additional functional issues were found in the modified code paths beyond the already-discussed prior threads.
  • No files require special attention

@openclaw-barnacle openclaw-barnacle bot added app: web-ui App: web-ui gateway Gateway runtime labels Feb 8, 2026
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@mcaxtr
Copy link
Contributor Author

mcaxtr commented Feb 8, 2026

@greptile review

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@mcaxtr
Copy link
Contributor Author

mcaxtr commented Feb 8, 2026

@greptile review

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@mcaxtr
Copy link
Contributor Author

mcaxtr commented Feb 8, 2026

@greptile review

@mcaxtr mcaxtr force-pushed the fix/11556-webchat-favicon-static branch 3 times, most recently from a1c6914 to 011e4bd Compare February 12, 2026 04:17
@mcaxtr mcaxtr force-pushed the fix/11556-webchat-favicon-static branch from 011e4bd to 7420570 Compare February 13, 2026 02:20
@mcaxtr mcaxtr force-pushed the fix/11556-webchat-favicon-static branch from 7420570 to c5f2f8c Compare February 13, 2026 14:34
@mcaxtr mcaxtr force-pushed the fix/11556-webchat-favicon-static branch 9 times, most recently from 4ad6212 to d9d4acf Compare February 15, 2026 14:44
@mcaxtr mcaxtr force-pushed the fix/11556-webchat-favicon-static branch 4 times, most recently from ba77a3e to 33b269d Compare February 19, 2026 13:10
@mcaxtr mcaxtr force-pushed the fix/11556-webchat-favicon-static branch from 33b269d to 6941bc0 Compare February 19, 2026 16:20
@mbelinky mbelinky force-pushed the fix/11556-webchat-favicon-static branch from 6941bc0 to 32d2ca7 Compare February 20, 2026 17:41
@mbelinky mbelinky merged commit 618b36f into openclaw:main Feb 20, 2026
10 checks passed
@mbelinky
Copy link
Contributor

Merged via squash.

Thanks @mcaxtr!

rodrigogs pushed a commit to rodrigogs/openclaw that referenced this pull request Feb 20, 2026
…lback (openclaw#12060)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 32d2ca7
Co-authored-by: mcaxtr <7562095+mcaxtr@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
Hansen1018 added a commit to Hansen1018/openclaw that referenced this pull request Feb 21, 2026
…lback (openclaw#12060)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 32d2ca7
Co-authored-by: mcaxtr <7562095+mcaxtr@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
vincentkoc pushed a commit that referenced this pull request Feb 21, 2026
…lback (#12060)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 32d2ca7
Co-authored-by: mcaxtr <7562095+mcaxtr@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
dgarson pushed a commit to dgarson/clawdbot that referenced this pull request Feb 21, 2026
…lback (openclaw#12060)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 32d2ca7
Co-authored-by: mcaxtr <7562095+mcaxtr@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
mmyyfirstb pushed a commit to mmyyfirstb/openclaw that referenced this pull request Feb 21, 2026
…lback (openclaw#12060)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 32d2ca7
Co-authored-by: mcaxtr <7562095+mcaxtr@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
obviyus pushed a commit to guirguispierre/openclaw that referenced this pull request Feb 22, 2026
…lback (openclaw#12060)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 32d2ca7
Co-authored-by: mcaxtr <7562095+mcaxtr@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
mreedr pushed a commit to mreedr/openclaw-custom that referenced this pull request Feb 24, 2026
…lback (openclaw#12060)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 32d2ca7
Co-authored-by: mcaxtr <7562095+mcaxtr@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…lback (openclaw#12060)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 32d2ca7
Co-authored-by: mcaxtr <7562095+mcaxtr@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
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: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Webchat path returns HTML for favicon.svg instead of serving static file (broken logo)

2 participants