Skip to content

fix(v2/devserver): don't dispatch runtime:ready from browser clients#5796

Open
Trainingdlu wants to merge 2 commits into
wailsapp:masterfrom
Trainingdlu:fix/devserver-runtime-ready-noise
Open

fix(v2/devserver): don't dispatch runtime:ready from browser clients#5796
Trainingdlu wants to merge 2 commits into
wailsapp:masterfrom
Trainingdlu:fix/devserver-runtime-ready-noise

Conversation

@Trainingdlu

@Trainingdlu Trainingdlu commented Jul 20, 2026

Copy link
Copy Markdown

Description

Fixes #5795.

The injected runtime always ends init with WailsInvoke("runtime:ready"). The desktop frontends consume it before dispatching; the dev server's websocket loop only special-cases drag, so browser clients pass it on to dispatcher.ProcessMessage, which routes on the first byte and has no case for r. Full trace in the issue.

This filters it alongside drag:

// Neither is a dispatcher message: drag is unsupported in browsers, and
// runtime:ready is consumed by the desktop frontends before they dispatch.
if m == "drag" || m == "runtime:ready" {
    return
}

Why discard it rather than replicate the desktop handling

DevWebServer embeds frontend.Frontend and doesn't override ExecJS, so the flags the desktop frontends set on runtime:ready only ever reach the desktop webview, never websocket clients. Browsers can't do window dragging anyway (that's why drag is discarded), and CanResolveFilePaths() is false there since it depends on chrome.webview.postMessageWithAdditionalObjects.

Same reason this doesn't extend to resize:, since enableResize is only ever set through ExecJS and a browser never emits it.

drag had a // We do not support drag in browsers comment in v2.9.1 saying much the same thing. It went missing in #4215 when the loop moved to gorilla/websocket, which is probably why runtime:ready never got added next to it.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Built a vanilla project against this branch with a replace directive.

Before: two error lines per browser page load. After: none.

Control: window.go.main.App.Greet("test") from the browser console still returns, and window.runtime.LogInfo(...) still reaches the terminal, so the filter isn't swallowing anything it shouldn't.

go test ./internal/... ./pkg/... passes, 24 packages.

No unit test included. The devserver package has no test files and the adjacent drag filter is untested too, so covering this would mean standing up a websocket + dispatcher + bindings harness for one condition. Can add one if you want it.

  • Windows
  • macOS
  • Linux

Test Configuration

# Wails
Version | v2.12.0

# System
| OS           | Windows 10 Home China                                              |
| Version      | 2009 (Build: 26200)                                                |
| ID           | 25H2                                                               |
| Go Version   | go1.26.4                                                           |
| Platform     | windows                                                            |
| Architecture | amd64                                                              |
| CPU          | Intel(R) Core(TM) i7-14700HX                                       |
| GPU 1        | NVIDIA GeForce RTX 4070 Laptop GPU (NVIDIA) - Driver: 32.0.15.8088 |
| GPU 2        | Intel(R) UHD Graphics (Intel Corporation) - Driver: 32.0.101.6790  |
| Memory       | 16GB                                                               |

# Dependencies
| Dependency | Package Name | Status    | Version       |
| WebView2   | N/A          | Installed | 150.0.4078.83 |
| Nodejs     | N/A          | Installed | 22.15.1       |
| npm        | N/A          | Installed | 10.9.2        |
| *upx       | N/A          | Available |               |
| *nsis      | N/A          | Available |               |

The CLI reports v2.12.0; the application under test was built against this branch via a replace directive.

Checklist:

  • (v2 only) I have updated website/src/pages/changelog.mdx with details of this PR (v3 changelog entries are added automatically)
  • My code follows the general coding style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (no user-facing docs affected)
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works (see above)
  • New and existing unit tests pass locally with my changes

Notes

Control messages consumed by the host are matched as exact strings, and each transport has to know its own list. runtime:ready is emitted regardless of transport, so all four need to account for it; the dev server was the one that didn't. Giving these a shared prefix the dispatcher could ignore would kill the whole class, but that's a protocol change and doesn't belong in this PR.

Not to be confused with #3714, which reports the same Unknown message from front end error from this same loop but for an unrelated reason (large payloads split across websocket frames are never reassembled). That one is a real functional bug and is not addressed here.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed development server handling of runtime readiness messages to prevent erroneous “Unknown message from front end” errors.
    • Improved filtering of unsupported development messages for more reliable local development behavior.
  • Documentation

    • Added the fix to the unreleased changelog.

The injected runtime unconditionally sends `runtime:ready` on init. The
desktop frontends consume it before dispatching, but the dev server only
filters `drag`, so browser clients send it straight to the dispatcher,
which rejects any message whose first character it does not recognise.

The result is two spurious error lines per page load, the second of which
reads "Unknown message from front end" and points at application code that
never sent the message.
Copilot AI review requested due to automatic review settings July 20, 2026 05:54
@github-actions github-actions Bot added Documentation Improvements or additions to documentation v2-only labels Jul 20, 2026
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The dev-server WebSocket handler now ignores runtime:ready alongside drag, preventing it from reaching application message dispatch. The changelog records the resulting fix for browser-client error logs.

Changes

Dev-server runtime filtering

Layer / File(s) Summary
Consume runtime control messages
v2/internal/frontend/devserver/devserver.go, website/src/pages/changelog.mdx
The WebSocket handler consumes drag and runtime:ready messages before dispatch, and the changelog documents the associated error fix.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Possibly related PRs

  • wailsapp/wails#4215: Updates the same dev-server WebSocket filtering logic for drag messages.

Suggested reviewers: copilot

Poem

I’m a bunny guarding the wire,
Runtime notes no longer catch fire.
“Ready” gets tucked away,
No noisy errors today—
Hop, hop, clean logs all the way!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The code filters runtime:ready in the dev server as requested by #5795, preventing browser clients from dispatching it.
Out of Scope Changes check ✅ Passed The changes stay focused on the runtime:ready devserver fix, with the changelog update and comments remaining in scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title is concise and accurately describes the main change: filtering runtime:ready in the v2 dev server.
Description check ✅ Passed The description matches the template well, includes the fixed issue, change summary, testing, configuration, and checklist.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
v2/internal/frontend/devserver/devserver.go (1)

199-203: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add a regression test for runtime:ready filtering.

Cover both cases: runtime:ready must not reach the dispatcher, while ordinary application messages must continue to dispatch normally.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@v2/internal/frontend/devserver/devserver.go` around lines 199 - 203, Add a
regression test around the devserver message filtering logic covering both
branches: verify that a "runtime:ready" message is not delivered to the
dispatcher, and verify that a normal application message still is. Reuse the
existing devserver test setup, dispatcher spy/mock, and message-dispatch entry
point rather than changing the filtering behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@v2/internal/frontend/devserver/devserver.go`:
- Around line 199-203: Add a regression test around the devserver message
filtering logic covering both branches: verify that a "runtime:ready" message is
not delivered to the dispatcher, and verify that a normal application message
still is. Reuse the existing devserver test setup, dispatcher spy/mock, and
message-dispatch entry point rather than changing the filtering behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1a7f7fb4-fae7-4760-9bb6-0f5ce3e60095

📥 Commits

Reviewing files that changed from the base of the PR and between 107e42c and dd0e1f1.

📒 Files selected for processing (2)
  • v2/internal/frontend/devserver/devserver.go
  • website/src/pages/changelog.mdx

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a v2 devserver noise issue where browser clients were causing runtime:ready to be forwarded into the dispatcher, resulting in repeated “Unknown message from front end” errors, even though the message is a runtime control signal.

Changes:

  • Filter runtime:ready in the devserver websocket IPC handler (alongside the existing drag filter) so it is not dispatched as an application message.
  • Add a changelog entry describing the fix and linking to #5795.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
v2/internal/frontend/devserver/devserver.go Prevents runtime:ready from reaching dispatcher.ProcessMessage for browser websocket clients.
website/src/pages/changelog.mdx Documents the fix in the Unreleased changelog under “Fixed”.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation Improvements or additions to documentation v2-only

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dev server logs "Unknown message from front end: runtime:ready" for every browser client

2 participants