MetaMask / MetaMask/metamask-extension
[Bug]: analytics-controller.init() not awaited Segment events sent with userId: undefined for opted in users
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 13.2k
- Forks
- 5.6k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 451
Description
### Describe the bug
`AnalyticsController.init()` is called without `await` in `app/scripts/messenger-client-init/analytics-controller-init.ts` (line 63), but `@metamask/analytics-controller@2.0.0` (the version locked in yarn.lock) made `init()` asynchronous a **breaking change** explicitly documented in its CHANGELOG:
> "AnalyticsController.init ... are now asynchronous and return a Promise, so **await them before tracking events**"
Inside `init()`, the call order is:
1. `await #maybeResolveLocation()` async geolocation network request (runs because `isGeolocationEnabled: true`)
2. `platformAdapter.onSetupCompleted(analyticsId)` **this sets `cachedAnalyticsId` in the platform adapter**
3. Replay queued events
Because `init()` is not awaited, `onSetupCompleted` hasn't run yet when the first analytics events fire after startup. The platform adapter's `cachedAnalyticsId` variable remains `undefined`, so all `track()` and `view()` calls send Segment payloads with `userId: undefined` until the geolocation network request completes.
This affects **all returning (already opted-in) users** on every startup.
### Expected behavior
All Segment track/view payloads include the correct userId (analyticsId). `controller.init()` must be awaited before any analytics events are tracked.
### Screenshots/Recordings
_No response_
### Steps to reproduce
1. Be a returning MetaMask user (already opted in to analytics)
2. Open MetaMask background service worker initializes AnalyticsController
3. Any analytics event fired during the geolocation resolution window is sent to Segment with userId: undefined
### Error messages or log output
```shell
No thrown error — silent data corruption.
Segment track/view payloads contain: { userId: undefined }
Root cause:
File: app/scripts/messenger-client-init/analytics-controller-init.ts, line 63
Current (buggy):
controller.init(); // Promise not awaited
Fix:
await controller.init();
Upstream CHANGELOG: https://github.com/MetaMask/core/blob/main/packages/analytics-controller/CHANGELOG.md#200
```
### Where was this bug found?
Live version (from official store)
### Version
12.x (main branch yarn.lock resolves @metamask/analytics-controller@2.0.0)
### Build type
_No response_
### Browser
Chrome
### Operating system
Windows, Linux
### Hardware wallet
_No response_
### Additional context
Related to the @metamask/analytics-controller@2.0.0 upgrade. The CHANGELOG for that package explicitly warns that init() is now async and must be awaited, but analytics-controller-init.ts was not updated accordingly.
### Severity
_No response_
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with app/scripts/messenger-client-init/analytics-controller-init.ts at line 63, then read the @metamask/analytics-controller 2.0.0 changelog entry about asynchronous init. Ensure initialization completes before startup analytics events are tracked, and verify that resulting Segment track/view payloads contain the analyticsId rather than undefined.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- analytics
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100