Repository navigation
Closed
Labels
P1High-priority issues at the top of the work listHigh-priority issues at the top of the work listplatform-webWeb applications specificallyWeb applications specificallyt: hot reloadReloading code during "flutter run"Reloading code during "flutter run"team-webOwned by Web platform teamOwned by Web platform teamtoolAffects the "flutter" command-line tool. See also t: labels.Affects the "flutter" command-line tool. See also t: labels.triaged-webTriaged by Web platform teamTriaged by Web platform team
Description
I am running flutter run --machine -d web-server --web-port 3000 --web-hostname 0.0.0.0 and hot reloading with
[
{
"method": "app.restart",
"id": 1,
"params": {
"appId": "e5a62088-0341-43ea-a18f-83aa691aab4f",
"fullRestart": false
}
}
]
sometimes fails as follows:
[{"event":"app.progress","params":{"appId":"e5a62088-0341-43ea-a18f-83aa691aab4f","id":"15","progressId":"hot.reload","message":"Performing hot reload...","finished":false}}]
[{"event":"app.progress","params":{"appId":"e5a62088-0341-43ea-a18f-83aa691aab4f","id":"16","progressId":null,"message":"Waiting for connection from debug service on Web Server...","finished":false}}]
Null check operator used on a null value
[{"event":"app.progress","params":{"appId":"e5a62088-0341-43ea-a18f-83aa691aab4f","id":"16","progressId":null,"finished":true}}]
[{"event":"app.progress","params":{"appId":"e5a62088-0341-43ea-a18f-83aa691aab4f","id":"15","progressId":"hot.reload","finished":true}}]
[{"id":1,"result":{"code":1,"message":"Failed to recompile application."}}]
I haven't been able to make much sense of it. The Null check operator used on a null value in there is curious. I have verified that the app under test does not have any nullability issues, so I suspect that something is crashing in the server during hot reload / recompilation.
I currently don't have a way to reproduce this reliably. I'll try to get more information on that... It's unfortunate that no stack trace is given...
Metadata
Metadata
Assignees
Labels
P1High-priority issues at the top of the work listHigh-priority issues at the top of the work listplatform-webWeb applications specificallyWeb applications specificallyt: hot reloadReloading code during "flutter run"Reloading code during "flutter run"team-webOwned by Web platform teamOwned by Web platform teamtoolAffects the "flutter" command-line tool. See also t: labels.Affects the "flutter" command-line tool. See also t: labels.triaged-webTriaged by Web platform teamTriaged by Web platform team
Activity
goderbauer commentedon Sep 3, 2026
cc @bkonyi sorry that this is so vague... I'll try to obtain more details...
goderbauer commentedon Sep 3, 2026
AI thinks that the "Null check operator used on a null value" exception is caught here and then forwarded without the stacktrace:
https://github.com/dart-lang/sdk/blob/cbdda8b4e08d686a811672e8e7de67bacb4afb43/pkg/frontend_server/lib/frontend_server.dart#L1324
As soon as I can I'll verify with https://dart-review.googlesource.com/c/sdk/+/545260 to see if I can get a stack trace out of it to verify and help with further debugging.
[frontend_server] Include stack trace when catching errors in recompi…
[frontend_server] Handle unreachable libraries during web incremental…
flutter-zl commentedon Sep 9, 2026
@goderbauer Do you ever hit the bug again and get the stacktrace?
goderbauer commentedon Sep 11, 2026
@flutter-zl I was able to capture the following stack trace:
With that, I can also confirm that https://dart-review.googlesource.com/c/sdk/+/545300 did not fix it :/ (FYI @bkonyi)
goderbauer commentedon Sep 11, 2026
AI tracked this down and also assisted in writing this comment :)
It's a different null check than the one 545300 fixed, which is why that CL didn't help.
Root cause
The
!is_generator.lastKnownGoodResult!inwriteJavaScriptBundle.lastKnownGoodResultis only populated byIncrementalCompiler.accept(), so it isnulluntil the client sends its firstaccept. ButrecompileDeltahardcodesfullComponent: falseand therefore always takes thebundler.invalidate(...)branch, which dereferences it.So the frontend server implicitly requires
compile→accept→recompile, and crashes oncompile→recompile. Nothing in the protocol enforces that ordering. It only affects DDC — the VM path (writeDillFile) never toucheslastKnownGoodResult.Why we hit it with
--machineAppDomain.startAppsends theapp.startevent (with theappId) beforerunner.run()is called:https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/commands/daemon.dart#L1025-L1068
Meanwhile
ResidentWebRunner.run()does the initial compile and only callsgenerator.accept()after_updateDevFS()has returned, i.e. after a fair amount of additional awaited work:https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart#L336-L343
So a client that already has the
appIdcan sendapp.restartin the window between "initial compile finished" and "acceptsent".ResidentCompilerserializes the requests, so therecompilelands right after thecompilebut before theaccept— andlastKnownGoodResultis stillnull. That explains why it's intermittent and why I couldn't reproduce it on demand.I suspect #152819 (same crash via the Debug Adapter, which is also
--machine) is the same root cause.Fix
Dart-side CL: https://dart-review.googlesource.com/c/sdk/+/548680
When there is no accepted delta, the bundler is initialized from the full component instead of diffing. That's exact rather than a workaround:
IncrementalCompiler.compile()returns_combinePendingDeltas(false), the union of all not-yet-accepted deltas, which is the same shape of component the initialcompilepasses tobundler.initialize.Reproduced deterministically in a test (
compile, thenrecompilewithoutaccept): it fails with exactlyNull check operator used on a null valuebefore the fix and passes after.Still open on the flutter side
The crash is gone, but the ordering is still wrong — an
app.restartthat races startup now silently causes a full bundle rebuild instead of a delta. Options:app.restartuntil the initialrun()has completed, orgenerator.accept()in the same synchronous continuation that observesreport.success, oroperationQueueas_queueAndDebounceReloadAction.@bkonyi @flutter-zl — worth fixing separately?
I'll also make sure that in our environment that surfaced this crash we will not issue
app.restartbeforeapp.startedis received to avoid this race altogether.[frontend_server] Don't crash when recompiling before the first accept
[tool] Defer app.restart until the app has finished starting (flutter…
github-actions commentedon Sep 29, 2026
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.