feat(error-tracking): report the injected release id on flutter web - #554
Draft
ablaszkiewicz wants to merge 1 commit into
Draft
feat(error-tracking): report the injected release id on flutter web#554ablaszkiewicz wants to merge 1 commit into
ablaszkiewicz wants to merge 1 commit into
Conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
posthog-flutter Compliance ReportDate: 2026-08-28 10:54:25 UTC ✅ All Tests Passed!45/45 tests passed Capture Tests✅ 29/29 tests passed View Details
Feature_Flags Tests✅ 16/16 tests passed View Details
|
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

💡 Motivation and Context
A Flutter web app that uploads its sourcemaps with
posthog-cli sourcemap inject --release-mode=eventgets a release id written intomain.dart.js. Nothing in the Dart SDK read it. The release still reached the event, because on web the plugin hands the exception to posthog-js and posthog-js reads the same global — but only posthog-js 1.409.0 and later. The page picks its own posthog-js, so an app on an older one silently loses the release its build injected.This reads the global in Dart, next to the chunk ids the SDK already reads there.
release_id.dart,release_id_web.dartandrelease_id_io.dartmirror the existingchunk_ids.darttrio. The io stub returns null: no chunk carries a release id outside the web build, and Apple and Android exceptions resolve their release from the app metadata the native SDK reports.DartExceptionProcessor.processExceptionputs it on the payload as$release_id, before user properties, so a caller can still override it.Nothing changes for an app that does not run
--release-mode=event, and nothing changes on Apple or Android.💚 How did you test it?
Two example apps in
error-tracking-examples, the same Flutter web app twice, differing only in the release mode their upload runs in. Each was run twice: a first release, then the same code again under a new version. Both built against this branch through a path dependency, and both reported into a local PostHog.All four exceptions symbolicated the full Dart call chain and resolved a release.
Flutter web (legacy)
First release
posthog-cli, flutter-web-legacy@5.0.0
The app page reads
injected $release_id: none, which is what legacy mode looks like. The release on the event came from the symbol set the upload bound to it.Second release, same code
posthog-cli, flutter-web-legacy@6.0.0
Legacy mints a fresh random chunk id on every build, so an unchanged 2.4 MB sourcemap uploads again as a second symbol set.
Flutter web (event mode)
First release
posthog-cli, flutter-web-releaseless@5.0.0
The app page prints the id it read out of the chunk, and the event carries the same one.
Second release, same code
posthog-cli, flutter-web-releaseless@6.0.0
1 skipped (1 already present)is the case the two examples exist to contrast. The chunk id comes from the content, so the sourcemap is unchanged and the stored symbol set is reused. The new release's id goes intomain.dart.js, and the exception reportsflutter-web-releaseless@6.0.0off that one symbol set.Both variants and all four releases land on one issue, each event carrying its own:
Deferred loading
flutter build webemits one sourcemapped chunk. An app that uses deferred loading gets one more per deferred library. A third build withimport 'heavy.dart' deferred as heavyproducedmain.dart.jsandmain.dart.js_1.part.js, the CLI found and injected both, and every frame carried its own chunk id:Both frames symbolicated, and the event resolved one release for the whole stack.
📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset fileDocs are unticked on purpose:
--release-modeis not documented on posthog.com for any platform yet, so a Flutter-only page would be the first. Happy to write it in a follow-up once the general docs land.🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Written by Claude Opus 5 in Claude Code. Skills invoked:
posthog-repos,asd-ste100,writing-pr-descriptions.The task started as "add event release mode support for Flutter", on the assumption the SDK needed the same work the other SDKs got. It did not. Reading
posthog_flutteronmainshowed the web handler already routes through posthog-js'scaptureException, and running it end to end confirmed the release reaches the event today. The change that survived is the narrower one: read the global in Dart so the release does not depend on which posthog-js the page loaded.Rejected along the way: reading the release id in the web method-channel handler instead of the processor, which would have missed the fallback path the handler keeps for old posthog-js builds.
The two example apps live in
PostHog/error-tracking-examplesonmain, asflutter-web-legacyandflutter-web-releaseless.