Skip to content

flutter run -d web-server: DWDS injected client crashes on startup, app stays blank until manual reload #125

Description

@teetangh

Summary

Running the app with flutter run -d web-server renders a blank page on first load. The Dart code does start (Sentry initialises, main() runs), but nothing paints until the page is manually reloaded, after which it renders and behaves normally.

The cause is an unhandled exception inside DWDS's injected debug client:

Unhandled error detected in the injected client.js script.

You can disable this script in webdev by passing --no-injected-client if it
is preventing your app from loading, but note that this will also prevent
all debugging and hot reload/restart functionality from working.

TypeError: Instance of '_JsonMap': type '_JsonMap' is not a subtype of type 'List<Object?>'
    at BuiltJsonSerializers._deserialize$3 (…/dwds/src/injected/client.js:20953:36)
    at Object._deserializeEvent (…/dwds/src/injected/client.js:9920:35)

This is an upstream dart-lang/webdev bug, not application code — filing here so it's documented rather than rediscovered.

Impact

Low severity, high confusion. It looks exactly like "the app is broken" or "the backend is unreachable":

  • Page is blank white, no error shown
  • Console shows only DDC is about to load 1/2 scripts and appears to hang
  • All assets return 200, so the network tab looks healthy

It bites hardest in automated/E2E contexts, where a blank first load can be misread as a genuine app failure. Relevant to prompts/testing/ which drives Flutter web via Chrome DevTools MCP.

Reproduction

flutter run -d web-server --web-hostname 127.0.0.1 --web-port 3000
# open http://localhost:3000 -> blank page
# reload -> app renders normally

Observed with Flutter 3.44.1 / Chrome 150.

Workarounds

  1. Reload the page once after first load. Simplest, keeps hot restart working.
  2. flutter run -d chrome instead — did not exhibit the stall in testing.
  3. For E2E runs where debugging isn't needed, serve a release build (flutter build web --release + any static server); no DWDS, no DDC, and it loads considerably faster.

Related gotcha worth recording

When driving Flutter web through Chrome DevTools:

  • The a11y snapshot is empty until semantics are enabled, because Flutter renders to canvas. Click the <flt-semantics-placeholder> element (aria-label "Enable accessibility") first, then the tree exposes real textboxes/buttons.
  • Filling a text field without clearing it first can leave a partial value — a 15-character password landed as 12 characters and produced a spurious 401 from a perfectly valid credential. Clear the field, then fill.

Both are worth adding to prompts/testing/README.md, which already notes Chrome DevTools MCP interaction as the main thing slowing prompt execution.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions