From c02a7562dec1afbb7d3dc6a6bd09c86636cc0646 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Tue, 16 Jun 2026 10:46:01 +0200 Subject: [PATCH 1/2] fix(android): Stop duplicating attachments on native events (JAVA-559) Scope attachments are synced to the native SDK, so native events already carry them as envelope items in the outbox. When re-ingesting those cached envelopes, SentryClient re-applied the scope attachments on top, sending each attachment twice. Skip re-applying scope attachments for cached envelopes. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/main/java/io/sentry/SentryClient.java | 4 +++- .../test/java/io/sentry/SentryClientTest.kt | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/sentry/src/main/java/io/sentry/SentryClient.java b/sentry/src/main/java/io/sentry/SentryClient.java index 5ac81c4493..78225f05d1 100644 --- a/sentry/src/main/java/io/sentry/SentryClient.java +++ b/sentry/src/main/java/io/sentry/SentryClient.java @@ -112,7 +112,9 @@ private boolean shouldApplyScopeData(final @NotNull CheckIn event, final @NotNul hint = new Hint(); } - if (shouldApplyScopeData(event, hint)) { + // Cached envelopes (e.g. native crashes from the outbox) already carry their attachments as + // envelope items. Re-applying scope attachments here would duplicate them. + if (shouldApplyScopeData(event, hint) && !HintUtils.hasType(hint, Cached.class)) { addScopeAttachmentsToHint(scope, hint); } diff --git a/sentry/src/test/java/io/sentry/SentryClientTest.kt b/sentry/src/test/java/io/sentry/SentryClientTest.kt index d5b2f0f82a..ab6fd2075a 100644 --- a/sentry/src/test/java/io/sentry/SentryClientTest.kt +++ b/sentry/src/test/java/io/sentry/SentryClientTest.kt @@ -870,6 +870,25 @@ class SentryClientTest { assertEquals(scope.level, event.level) } + @Test + fun `when hint is Cached, scope attachments are not added to avoid duplication`() { + val sut = fixture.getSut() + + val event = createEvent() + val scope = createScopeWithAttachments() + + val hints = HintUtils.createWithTypeCheckHint(CustomCachedApplyScopeDataHint()) + sut.captureEvent(event, scope, hints) + + verify(fixture.transport) + .send( + check { actual -> + assertEquals(0, actual.items.count { it.header.type == SentryItemType.Attachment }) + }, + anyOrNull(), + ) + } + @Test fun `when transport factory is NoOp, it should initialize it`() { fixture.sentryOptions.setTransportFactory(NoOpTransportFactory.getInstance()) From 04dff861e9a3d5f938cdc9e13bf102813e8faf69 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Tue, 16 Jun 2026 10:47:01 +0200 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 648533ec18..93cd3765da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ ### Fixes +- Fix attachments being duplicated on native events that carry scope attachments ([#5548](https://github.com/getsentry/sentry-java/pull/5548)) - Fix performance collector scheduling many tasks in a row ([#5524](https://github.com/getsentry/sentry-java/pull/5524)) ## 8.43.2