fix: clear analytics queue on callback errors#8934
Merged
Conversation
7 tasks
There was a problem hiding this comment.
Pull request overview
This PR updates AnalyticsController’s persisted event-queue behavior so queued analytics entries are removed once the platform adapter’s delivery callback fires, even when that callback reports an error. This prevents permanently failing/malformed events from being replayed on restart and aligns cleanup semantics with the prior Segment-backed MetaMetrics behavior.
Changes:
- Remove the early-return on callback error so queued events are always removed after the delivery callback runs.
- Update the event-queue persistence tests to assert queue cleanup on callback error and adjust a mutation test to avoid triggering callback-driven removal.
- Document the behavior change in the
analytics-controllerpackage changelog.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/analytics-controller/src/AnalyticsController.ts | Always clears a queued event after the adapter callback runs (success or error). |
| packages/analytics-controller/src/AnalyticsController.test.ts | Updates expectations for callback-error behavior and keeps clone-mutation test stable under new semantics. |
| packages/analytics-controller/CHANGELOG.md | Notes the fixed queue-cleanup behavior in Unreleased. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
itsyoboieltr
approved these changes
Jun 5, 2026
HowardBraham
pushed a commit
to consensys-test/metamask-extension-howard
that referenced
this pull request
Jun 5, 2026
## **Description**
This PR integrates AnalyticsController in Extension codebase.
It replaces this state:
- MetaMetricsController's `metaMetricsId`
- MetaMetricsController's `participateInMetaMetrics`
- MetaMetricsController's `segmentApiCalls`
by this state:
- AnalyticsController's `analyticsId`
- AnalyticsController's `optedIn`
- AnalyticsController's `eventQueue`
- MetaMetricsController's `completedMetaMetricsOnboarding`
Since these changes impact many areas of the codebase, we’ve decided to
take a phased approach.
This PR migrates the persisted state and updates the UI compatibility
selectors, as well as the background `getState()` function, to derive
the legacy values (`metaMetricsId`, `participateInMetaMetrics`) from the
new state. This lets existing code continue using the legacy values
while the source of truth moves to `AnalyticsController.analyticsId`,
`AnalyticsController.optedIn`, and
`MetaMetricsController.completedMetaMetricsOnboarding`.
In future phases, we’ll progressively remove all remaining usages of the
legacy values (`metaMetricsId`, `participateInMetaMetrics`) throughout
the codebase.
The files that deserve more attention during PR review are the
following:
- app/scripts/controllers/analytics/platform-adapter.ts
- app/scripts/controllers/metametrics-controller.ts
```mermaid
flowchart TB
subgraph Before["Before"]
direction LR
MMC1["MetaMetricsController"] --> SDK1["Segment SDK"]
Early1["Early events"] --> SDK1
end
subgraph After["After"]
direction LR
MMC2["MetaMetricsController"] --> AC["AnalyticsController"]
AC --> SDK2["Segment SDK"]
Early2["Early events"] --> SDK2
end
Before ~~~ After
```
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes: MetaMask/MetaMask-planning#7193
## **Manual testing steps**
Main test case
1. Build two different Extensions, one on this branch and one on main,
the goal will be to compare events emitted by both and confirm they're
equivalent
2. Go through onboarding with both extension and find your
metaMetricsId/analyticsId by doing right click on extension UI, then
inspect > Application > Storage > IndexedDB > metamask-backup >
MetaMetricsController/AnalyticsController
3. Open Segment, choose the right source (usually `MetaMask Extension
[Dev]`, except if you configured SEGMENT_WRITE_KEY env variable with
your own Segment project), and filter events with your
metaMetricsId/analyticsId
4. Confirm the three types of events emitted by both extension are
equivalent:
a. track
b. identify
c. page
Edge cases
- Anonymous events (see list
[here](MetaMask/MetaMask-planning#7230))
- Fully anonymous ones
- These events are fully anonymous in the sense that the entire event,
including all properties are considered as sensitive and get anonymized
- Fully anonymous events are emitted by passing "excludeMetaMetricsId:
true" as option (Example
[here](https://github.com/MetaMask/metamask-extension/blob/main/app/scripts/background.js#L502))
- An easy one to reproduce is "Phishing Page Displayed": visit one of
the pages listed
[here](https://phishing-detection.api.cx.metamask.io/v1/stalelist) and
the event will be emitted
- Partially anonymous ones
- These events are partially anonymous in the sense that some properties
are considered as sensitive and some are not. As a consequence, 2 events
are sent: an anonymous one with all properties, and a non-anonymous one
with only properties considered as non-sensitive
- Partially anonymous events are emitted by passing
"sensitiveProperties" (Example
[here](https://github.com/MetaMask/metamask-extension/blob/main/ui/pages/contacts/components/add-contact-form.tsx#L236-L239))
- An easy one to reproduce is "Contact Added": go to Contacts, click
"Add contact", and add Vitalik's address as contact
(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045)
- Before this PR, both events used to have similar messageId (example:
"1780055175321.6592", and "1780055175321.6592-0x000"), while with this
PR, messageId have a new uuidv4 format and both events don't have
similar messageId (example: "5cc0d85e-3f0e-4374-8811-d36924d06689" and
"433ff4c1-948d-4a4e-9470-81e878c7df44")
- Anonymous ones with event renaming
- Some anonymous events get renamed when being emitted (list of events
available
[here](https://github.com/MetaMask/metamask-extension/blob/main/app/scripts/controllers/metametrics-controller.ts#L113-L130)):
for example “Signature Requested” gets renamed “Signature Requested
Anon”
- An easy one to reproduce is “Signature Requested” (see Fragments
sections below for more detail)
- Fragments
- Fragments are events used to tie a multi-step flow together, such as
“Signature Requested” followed later by “Signature Approved” or
“Signature Rejected”
- They can be tested by visiting
[test-dapp](https://metamask.github.io/test-dapp/), then connect
extension, then click "Sign Typed Data V4", then accept or reject
signature
- The purpose of fragments is for both each event of the multi-step flow
to share the same properties
- Before this PR, events from a same fragment used to have similar
`messageId` (example: "signature-3947127447", and
"signature-3947127447-success" or "signature-3947127447-failure"), while
with this PR, `messageId` have a new uuidv4 format and events from a
same fragment don't have similar `messageId` (example:
"9e3a83d0-ce13-47d2-a2f4-08a6d9adc29d" and
"d2368a25-01c5-4b3c-af55-7d5f54eb58a6")
- Persisted queue
- Go to home page
- Check that persisted queue is an empty object: right click on
extension UI, then inspect > Application > Storage > IndexedDB >
metamask-backup > MetaMetricsController/AnalyticsController >
segmentApiCalls/eventQueue
- Turn internet off
- Click on "Swap"
- Confirm no event is sent to Segment
- Confirm events are added to persisted queue, including "Unified
SwapBridge Button Clicked" (click on refresh button in the inspector to
see them)
- Wait for 5 minutes
- Turn internet on
- Restart extension
- Confirm events are sent to Segment, including "Unified SwapBridge
Button Clicked", and there's a 5 minute difference between `timestamp`
and `sentAt`
- These repro steps are not working on main branch, because persisted
queue used to get cleared, regardless of whether the callback represents
success or failure, whereas in this PR, it only gets cleared upon
success. That change of behavior introduces the risk that if an event is
malformed, it can end up being retried after every extension restart.
But at the same time it allows us to collect more events, in cases of
transient failures (e.g. offline, timeout). This core repo PR got opened
to align behavior with what's currently on main:
MetaMask/core#8934
- Early events
- Right click on extension UI, then inspect > Application > Storage >
Extension storage > Local > KeyringController > Right click to delete
KeyringController
- Restart Extension straight away
- You should see "Vault Corruption Restore Wallet Screen Viewed" event
in Segment
- Opt out event
- Start from a fresh onboarding state, go through create/import wallet,
on the MetaMetrics onboarding page, uncheck “Participate in
MetaMetrics”, continue and finish onboarding.
- On Chrome, you should see "Metrics Opt Out" event in Segment
- On Firefox, you should not see "Metrics Opt Out" event in Segment
- Delete metametrics
- Right click on extension UI, then inspect > Network, and paste
"regulations" in the search bar
- Go to Settings > Privacy > Delete MetaMetrics data and click the
button
- You should see an API call in the Networks tab, with "subjectIds"
array as parameter, and your metaMetricsId/analyticsId included in that
array
## **Screenshots/Recordings**
NA
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **High Risk**
> Central refactor of consent, IDs, queuing, and anonymous event
handling across background, Segment, and data-deletion paths; messageId
and offline-queue behavior differ from main and can affect metrics
parity or stuck retries.
>
> **Overview**
> This PR routes MetaMetrics **track / identify / page** through
**`AnalyticsController`** and a new **Segment `platform-adapter`**,
instead of **`MetaMetricsController`** calling Segment directly.
>
> **State & consent:** Persisted **`metaMetricsId`**,
**`participateInMetaMetrics`**, and **`segmentApiCalls`** are removed
from **`MetaMetricsController`** in favor of **`AnalyticsController`**
(`analyticsId`, `optedIn`, `eventQueue`) plus
**`completedMetaMetricsOnboarding`**. Opt-in/out now calls
**`AnalyticsController:optIn` / `optOut`**; IDs come from
**`getMetaMetricsId()`** → analytics state. **Sentry** snapshots add
**`AnalyticsController`** and drop the old MMC consent fields.
>
> **Behavior changes:** Anonymous / sensitive events use a
**`properties.anonymous`** marker; the adapter swaps to the shared
anonymous ID and renames select signature/transaction events. Direct
Segment logic (payload building, **`segmentApiCalls`** MV3 replay,
deterministic **`messageId`**, **`generateMetaMetricsId`**) is removed
from MMC. **Early** and **opt-out** paths use
**`custom-segment-tracking`** reading **`AnalyticsController`** from
backup state. **RPC middleware**, **data deletion**, and **background**
helpers read consent/ID via **`controller.getState()`** /
**`analyticsController.state`**.
>
> **Tests:** Large **`metametrics-controller`** test updates; new
**`platform-adapter`** unit tests.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5d73b11. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Norbert Elter <72046715+itsyoboieltr@users.noreply.github.com>
pull Bot
pushed a commit
to dmrazzy/core
that referenced
this pull request
Jun 8, 2026
## Explanation This is the release candidate for version `1023.0.0`. It releases `@metamask/analytics-controller@1.1.1`, which clears persisted analytics event queue entries after the delivery callback runs, including when the callback reports an error ([MetaMask#8934](MetaMask#8934)). ## References <!-- Are there any issues that this pull request is tied to? Are there other links that reviewers should consult to understand these changes better? Are there client or consumer pull requests to adopt any breaking changes? --> ## Checklist - [ ] I've updated the test suite for new or updated code as appropriate - [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [ ] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md) - [ ] I've introduced [breaking changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md) in this PR and have prepared draft pull requests for clients and consumer packages to resolve them <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Version and changelog-only release with no code changes in this PR; shipped fix is a patch-level analytics queue persistence behavior. > > **Overview** > **Monorepo release `1023.0.0`** bumps the root `package.json` version from `1022.0.0` to `1023.0.0`. > > It publishes **`@metamask/analytics-controller@1.1.1`** (from `1.1.0`) with changelog entries for the fix in [MetaMask#8934](MetaMask#8934): persisted analytics event queue entries are cleared after the delivery callback runs, including when the callback reports an error. > > This PR contains **version and changelog updates only**; the behavioral fix is not in this diff. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit b711b05. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
sgextcsi
pushed a commit
to sgextcsi/metamask-extension-ne-regression
that referenced
this pull request
Jun 8, 2026
## **Description**
This PR integrates AnalyticsController in Extension codebase.
It replaces this state:
- MetaMetricsController's `metaMetricsId`
- MetaMetricsController's `participateInMetaMetrics`
- MetaMetricsController's `segmentApiCalls`
by this state:
- AnalyticsController's `analyticsId`
- AnalyticsController's `optedIn`
- AnalyticsController's `eventQueue`
- MetaMetricsController's `completedMetaMetricsOnboarding`
Since these changes impact many areas of the codebase, we’ve decided to
take a phased approach.
This PR migrates the persisted state and updates the UI compatibility
selectors, as well as the background `getState()` function, to derive
the legacy values (`metaMetricsId`, `participateInMetaMetrics`) from the
new state. This lets existing code continue using the legacy values
while the source of truth moves to `AnalyticsController.analyticsId`,
`AnalyticsController.optedIn`, and
`MetaMetricsController.completedMetaMetricsOnboarding`.
In future phases, we’ll progressively remove all remaining usages of the
legacy values (`metaMetricsId`, `participateInMetaMetrics`) throughout
the codebase.
The files that deserve more attention during PR review are the
following:
- app/scripts/controllers/analytics/platform-adapter.ts
- app/scripts/controllers/metametrics-controller.ts
```mermaid
flowchart TB
subgraph Before["Before"]
direction LR
MMC1["MetaMetricsController"] --> SDK1["Segment SDK"]
Early1["Early events"] --> SDK1
end
subgraph After["After"]
direction LR
MMC2["MetaMetricsController"] --> AC["AnalyticsController"]
AC --> SDK2["Segment SDK"]
Early2["Early events"] --> SDK2
end
Before ~~~ After
```
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes: MetaMask/MetaMask-planning#7193
## **Manual testing steps**
Main test case
1. Build two different Extensions, one on this branch and one on main,
the goal will be to compare events emitted by both and confirm they're
equivalent
2. Go through onboarding with both extension and find your
metaMetricsId/analyticsId by doing right click on extension UI, then
inspect > Application > Storage > IndexedDB > metamask-backup >
MetaMetricsController/AnalyticsController
3. Open Segment, choose the right source (usually `MetaMask Extension
[Dev]`, except if you configured SEGMENT_WRITE_KEY env variable with
your own Segment project), and filter events with your
metaMetricsId/analyticsId
4. Confirm the three types of events emitted by both extension are
equivalent:
a. track
b. identify
c. page
Edge cases
- Anonymous events (see list
[here](MetaMask/MetaMask-planning#7230))
- Fully anonymous ones
- These events are fully anonymous in the sense that the entire event,
including all properties are considered as sensitive and get anonymized
- Fully anonymous events are emitted by passing "excludeMetaMetricsId:
true" as option (Example
[here](https://github.com/MetaMask/metamask-extension/blob/main/app/scripts/background.js#L502))
- An easy one to reproduce is "Phishing Page Displayed": visit one of
the pages listed
[here](https://phishing-detection.api.cx.metamask.io/v1/stalelist) and
the event will be emitted
- Partially anonymous ones
- These events are partially anonymous in the sense that some properties
are considered as sensitive and some are not. As a consequence, 2 events
are sent: an anonymous one with all properties, and a non-anonymous one
with only properties considered as non-sensitive
- Partially anonymous events are emitted by passing
"sensitiveProperties" (Example
[here](https://github.com/MetaMask/metamask-extension/blob/main/ui/pages/contacts/components/add-contact-form.tsx#L236-L239))
- An easy one to reproduce is "Contact Added": go to Contacts, click
"Add contact", and add Vitalik's address as contact
(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045)
- Before this PR, both events used to have similar messageId (example:
"1780055175321.6592", and "1780055175321.6592-0x000"), while with this
PR, messageId have a new uuidv4 format and both events don't have
similar messageId (example: "5cc0d85e-3f0e-4374-8811-d36924d06689" and
"433ff4c1-948d-4a4e-9470-81e878c7df44")
- Anonymous ones with event renaming
- Some anonymous events get renamed when being emitted (list of events
available
[here](https://github.com/MetaMask/metamask-extension/blob/main/app/scripts/controllers/metametrics-controller.ts#L113-L130)):
for example “Signature Requested” gets renamed “Signature Requested
Anon”
- An easy one to reproduce is “Signature Requested” (see Fragments
sections below for more detail)
- Fragments
- Fragments are events used to tie a multi-step flow together, such as
“Signature Requested” followed later by “Signature Approved” or
“Signature Rejected”
- They can be tested by visiting
[test-dapp](https://metamask.github.io/test-dapp/), then connect
extension, then click "Sign Typed Data V4", then accept or reject
signature
- The purpose of fragments is for both each event of the multi-step flow
to share the same properties
- Before this PR, events from a same fragment used to have similar
`messageId` (example: "signature-3947127447", and
"signature-3947127447-success" or "signature-3947127447-failure"), while
with this PR, `messageId` have a new uuidv4 format and events from a
same fragment don't have similar `messageId` (example:
"9e3a83d0-ce13-47d2-a2f4-08a6d9adc29d" and
"d2368a25-01c5-4b3c-af55-7d5f54eb58a6")
- Persisted queue
- Go to home page
- Check that persisted queue is an empty object: right click on
extension UI, then inspect > Application > Storage > IndexedDB >
metamask-backup > MetaMetricsController/AnalyticsController >
segmentApiCalls/eventQueue
- Turn internet off
- Click on "Swap"
- Confirm no event is sent to Segment
- Confirm events are added to persisted queue, including "Unified
SwapBridge Button Clicked" (click on refresh button in the inspector to
see them)
- Wait for 5 minutes
- Turn internet on
- Restart extension
- Confirm events are sent to Segment, including "Unified SwapBridge
Button Clicked", and there's a 5 minute difference between `timestamp`
and `sentAt`
- These repro steps are not working on main branch, because persisted
queue used to get cleared, regardless of whether the callback represents
success or failure, whereas in this PR, it only gets cleared upon
success. That change of behavior introduces the risk that if an event is
malformed, it can end up being retried after every extension restart.
But at the same time it allows us to collect more events, in cases of
transient failures (e.g. offline, timeout). This core repo PR got opened
to align behavior with what's currently on main:
MetaMask/core#8934
- Early events
- Right click on extension UI, then inspect > Application > Storage >
Extension storage > Local > KeyringController > Right click to delete
KeyringController
- Restart Extension straight away
- You should see "Vault Corruption Restore Wallet Screen Viewed" event
in Segment
- Opt out event
- Start from a fresh onboarding state, go through create/import wallet,
on the MetaMetrics onboarding page, uncheck “Participate in
MetaMetrics”, continue and finish onboarding.
- On Chrome, you should see "Metrics Opt Out" event in Segment
- On Firefox, you should not see "Metrics Opt Out" event in Segment
- Delete metametrics
- Right click on extension UI, then inspect > Network, and paste
"regulations" in the search bar
- Go to Settings > Privacy > Delete MetaMetrics data and click the
button
- You should see an API call in the Networks tab, with "subjectIds"
array as parameter, and your metaMetricsId/analyticsId included in that
array
## **Screenshots/Recordings**
NA
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **High Risk**
> Central refactor of consent, IDs, queuing, and anonymous event
handling across background, Segment, and data-deletion paths; messageId
and offline-queue behavior differ from main and can affect metrics
parity or stuck retries.
>
> **Overview**
> This PR routes MetaMetrics **track / identify / page** through
**`AnalyticsController`** and a new **Segment `platform-adapter`**,
instead of **`MetaMetricsController`** calling Segment directly.
>
> **State & consent:** Persisted **`metaMetricsId`**,
**`participateInMetaMetrics`**, and **`segmentApiCalls`** are removed
from **`MetaMetricsController`** in favor of **`AnalyticsController`**
(`analyticsId`, `optedIn`, `eventQueue`) plus
**`completedMetaMetricsOnboarding`**. Opt-in/out now calls
**`AnalyticsController:optIn` / `optOut`**; IDs come from
**`getMetaMetricsId()`** → analytics state. **Sentry** snapshots add
**`AnalyticsController`** and drop the old MMC consent fields.
>
> **Behavior changes:** Anonymous / sensitive events use a
**`properties.anonymous`** marker; the adapter swaps to the shared
anonymous ID and renames select signature/transaction events. Direct
Segment logic (payload building, **`segmentApiCalls`** MV3 replay,
deterministic **`messageId`**, **`generateMetaMetricsId`**) is removed
from MMC. **Early** and **opt-out** paths use
**`custom-segment-tracking`** reading **`AnalyticsController`** from
backup state. **RPC middleware**, **data deletion**, and **background**
helpers read consent/ID via **`controller.getState()`** /
**`analyticsController.state`**.
>
> **Tests:** Large **`metametrics-controller`** test updates; new
**`platform-adapter`** unit tests.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5d73b11. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Norbert Elter <72046715+itsyoboieltr@users.noreply.github.com>
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.
Explanation
Clear persisted analytics queue entries once the platform adapter delivery callback fires, even when the callback receives an error. This aligns queue cleanup behavior with the previous Segment-backed MetaMetrics flow and avoids repeatedly replaying malformed or permanently failing events on restart.
References
NA
For example:
Checklist
Note
Medium Risk
Changes when persisted analytics events are dropped versus retried; events reported as failed by the adapter will not be re-sent after restart, which is intentional but affects delivery reliability semantics.
Overview
When persisted event-queue delivery runs,
AnalyticsControllernow removes queued entries as soon as the platform adapter’s delivery callback fires, including when the callback passes an error. Failed deliveries are still logged; the queue is no longer left intact for those cases.That matches prior Segment-backed MetaMetrics behavior and stops replaying events that already failed delivery (for example malformed or permanently rejected payloads) on the next startup. Queued items are still retained if the adapter throws synchronously before the callback runs.
Tests and the package changelog were updated for the new cleanup behavior.
Reviewed by Cursor Bugbot for commit 18ab987. Bugbot is set up for automated code reviews on this repo. Configure here.