Repository navigation
[web] Stale web_plugin_registrant.dart reused when plugin set changes — newly added plugins silently never register in built apps #189128
Copy link
Copy link
Closed
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work lista: buildBuilding flutter applications with the toolBuilding flutter applications with the toolfyi-webFor the attention of Web platform teamFor the attention of Web platform teamplatform-webWeb applications specificallyWeb applications specificallyteam-toolOwned by Flutter Tool teamOwned by Flutter Tool teamtoolAffects the "flutter" command-line tool. See also t: labels.Affects the "flutter" command-line tool. See also t: labels.triaged-toolTriaged by Flutter Tool teamTriaged by Flutter Tool team
Description
Activity
Prior-art survey (searched GitHub, StackOverflow, and the wider web for earlier reports of this mechanism):
- Regenerate Dart plugin registrant after a hot restart #76219 (2021, P1, closed) is the closest precedent: the same class of staleness — plugin registrant not regenerated after a
pubspec.yamlplugin change — was reported and fixed for the hot-restart path back then. This issue is the same failure class surviving in theflutter build webpath: the registrant target is not invalidated when the plugin set changes between two non-empty states. - [Bug]: fluttercommunity/plus_plugins#1976 (2023, closed) appears to be a wild sighting of the loud variant of this bug: after upgrading
package_info_pluspast the version where the separatepackage_info_plus_webpackage was discontinued, the user'sflutter build web --releasefailed compiling a.dart_tool/flutter_build/<hash>/web_plugin_registrant.dartthat still imported the discontinuedpackage_info_plus_web— i.e., a stale registrant from before the upgrade. It was closed as a user import error, but the offending import is in the generated file, andflutter cleanwould have "fixed" it — consistent with the mechanism described here. - StackOverflow currently has no questions mentioning
web_plugin_registrantat all; the symptoms appear to get absorbed by generic "runflutter clean" folklore without the tool bug being identified, which is likely why the silent add-a-plugin variant hasn't been reported until now.
- Regenerate Dart plugin registrant after a hot restart #76219 (2021, P1, closed) is the closest precedent: the same class of staleness — plugin registrant not regenerated after a
- addedin triagePresently being triaged by the triage teamPresently being triaged by the triage team
on Jul 9, 2026 @forTheSakeOfLogic Thank you for this exceptionally high-quality and thorough bug report. Providing a 5-command reproduction case makes it very easy to verify.
I have reproduced the issue and confirmed that the build-cache fingerprinting logic in
flutter_toolsis failing to invalidate the stale registrant file. I am labeling and routing this to theteam-toolto investigate.- addedtoolAffects the "flutter" command-line tool. See also t: labels.Affects the "flutter" command-line tool. See also t: labels.platform-webWeb applications specificallyWeb applications specificallyteam-toolOwned by Flutter Tool teamOwned by Flutter Tool teama: buildBuilding flutter applications with the toolBuilding flutter applications with the toolfyi-webFor the attention of Web platform teamFor the attention of Web platform teamand removedin triagePresently being triaged by the triage teamPresently being triaged by the triage team
on Jul 9, 2026 - added a commit that references this issue
on Jul 14, 2026 - addedP2Important issues not at the top of the work listImportant issues not at the top of the work listtriaged-toolTriaged by Flutter Tool teamTriaged by Flutter Tool team
on Jul 14, 2026 - added a commit that references this issue
on Jul 23, 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.- locked as resolved and limited conversation to collaborators
on Aug 6, 2026
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work lista: buildBuilding flutter applications with the toolBuilding flutter applications with the toolfyi-webFor the attention of Web platform teamFor the attention of Web platform teamplatform-webWeb applications specificallyWeb applications specificallyteam-toolOwned by Flutter Tool teamOwned by Flutter Tool teamtoolAffects the "flutter" command-line tool. See also t: labels.Affects the "flutter" command-line tool. See also t: labels.triaged-toolTriaged by Flutter Tool teamTriaged by Flutter Tool team
Steps to reproduce
The whole reproduction is five CLI commands from a fresh
flutter create— no project download needed:Actual result (after step 3 — the second build "succeeds"):
PackageInfoPlusWebPlugin.registerWith(...)is missing. The generatedweb_plugin_registrant.dartwas not regenerated when the plugin set changed; the build directory (same hash, e.g..dart_tool/flutter_build/522e0d9d…) was reused with the stale file, and the stale registrant is what gets compiled intomain.dart.js. The newly added plugin's web implementation silently never registers in the shipped app.Expected result:
which is exactly what you get after
flutter clean && flutter build web --release.The loud inverse variant (proves the staleness directly)
Going the other direction fails loudly instead of silently. In a project that has built web release with N plugins, remove a plugin from
pubspec.yaml,flutter pub get, and rebuild:The build tries to compile the stale registrant, which still imports the removed package. Same root cause, opposite symptom: the registrant target is not invalidated when the plugin set changes (as long as both states have ≥ 1 plugin, so the build-directory hash stays the same — going from zero plugins to some plugins changes the hash and regenerates correctly, which is why single-shot fresh repros never catch this).
How this bites in production (real-world impact)
We hit this in a real app and it was brutal to diagnose:
The app used Firebase (web) and was developed for weeks with
flutter run -d chrome— debug is unaffected (different build pipeline/artifacts), so everything worked daily.The first-ever
flutter build web --release+ deploy produced a blank white screen. The project's long-lived.dart_toolstill contained registrants generated before the Firebase plugins were added (we later found multiple staleweb_plugin_registrant.dartfiles from different eras of the project sitting in differentflutter_build/<hash>/dirs).With no
FirebaseCoreWebregistered,FirebasePlatform.instancesilently fell back to the method-channel default andFirebase.initializeApp()threw:which killed
main()beforerunApp→ pure white page. In minified release the console shows only a bare"Uncaught ", so we had to attach CDP to extract the Dart exception.The misdirection potential is extreme:
flutter build web --profileof the same tree worked (different build args → differentflutter_build/<hash>dir → freshly generated registrant), which made it look like a dart2js/minification bug. Checking out an older commit into a fresh worktree also "worked" (clean dir), which made it look like a recently-added package was the culprit. Both were red herrings — it was the stale registrant all along.Existing reports of
channel-error …initializeCoreare all mobile-native registration problems; we found no issue describing this web build-cache mechanism, and searching for the actual cause is nearly impossible from the symptom.Anyone with a long-lived checkout who added a web-relevant plugin after their first web build, and whose CI/dev flow doesn't happen to run
flutter clean, can ship an app with silently unregistered plugins (MissingPluginException/channel-error/ features no-oping at runtime).Workarounds
flutter cleanbefore release web builds (or delete.dart_tool/flutter_build), ormain()via a conditional-import shim that mirrors the generated registrant (registering twice is harmless).Expected behaviour
flutter build webshould regenerate (or invalidate)web_plugin_registrant.dartwhenever the resolved plugin set changes — plugin additions/removals inpubspec.yamlmust be part of the fingerprint that decides whether the registrant (and the kernel/dart2js outputs that depend on it) are up to date.Flutter Doctor output
flutter doctor -v
Reproduced with
flutter build web --release(also applies with default args; debugflutter runis unaffected;--profileappeared unaffected only because the different args select a different cached build directory).Transparency note: this bug was diagnosed and this report was written by Claude (Anthropic's Fable 5 model) working in Claude Code, at the request and with the permission of this account's owner, who asked that the investigation be credited accurately. Happy to provide any additional detail from the diagnostic session (CDP traces, the stale registrant files from the affected project, etc.) via the account owner.