From 1b0b9e0b4c5e17cac9d6fb4f878afe2b6dfb9a2e Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Thu, 29 Oct 2026 00:27:43 +0000 Subject: [PATCH 1/2] perf(cli): Skip adjacent-event lookups on project event details @sentry/api 0.423.0 (bumped in #1713) defaults `collapse=adjacentEvents` on getOrganizationIssueEvent and getProjectEvent. CLI getEvent() now sends it on the project event-details endpoint too (supported since getsentry/sentry#129123), and getLatestEvent() drops the explicit param it added in #1705 in favor of the SDK default. Tests assert both requests still carry the param. Co-Authored-By: BYK --- packages/cli/src/lib/api/events.ts | 9 --------- packages/cli/test/lib/api-client.coverage.test.ts | 3 +++ packages/toolkit-core/src/response-cache/tiers.test.ts | 8 ++++++++ packages/toolkit-core/src/response-cache/tiers.ts | 5 +++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/cli/src/lib/api/events.ts b/packages/cli/src/lib/api/events.ts index 678bda9ea..8b08dca80 100644 --- a/packages/cli/src/lib/api/events.ts +++ b/packages/cli/src/lib/api/events.ts @@ -6,7 +6,6 @@ import { type EventAttachmentDetailsResponse, - type GetOrganizationIssueEventData, getOrganizationIssueEvent, getProjectEvent, listOrganizationIssueEvents, @@ -44,13 +43,6 @@ export async function getLatestEvent( issueId: string, ): Promise { const config = await getOrgSdkConfig(orgSlug); - // `collapse=adjacentEvents` lets Sentry skip the next/previous-event Snuba - // lookups; the CLI never reads `nextEventID` or `previousEventID`. The - // generated query type omits `collapse`, so the intersection keeps the - // server-supported parameter without weakening the generated client type. - const query: NonNullable & { - collapse: string[]; - } = { collapse: ["adjacentEvents"] }; const result = await getOrganizationIssueEvent({ ...config, @@ -59,7 +51,6 @@ export async function getLatestEvent( issue_id: issueId, event_id: "latest", }, - query, }); return unwrapResult(result, "Failed to get latest event"); diff --git a/packages/cli/test/lib/api-client.coverage.test.ts b/packages/cli/test/lib/api-client.coverage.test.ts index 374c65940..3c479b198 100644 --- a/packages/cli/test/lib/api-client.coverage.test.ts +++ b/packages/cli/test/lib/api-client.coverage.test.ts @@ -1029,6 +1029,9 @@ describe("events.ts", () => { expect(req.url).toContain( "/projects/test-org/test-project/events/evt-abc/", ); + expect(new URL(req.url).searchParams.getAll("collapse")).toEqual([ + "adjacentEvents", + ]); return new Response(JSON.stringify(event), { status: 200, headers: { "Content-Type": "application/json" }, diff --git a/packages/toolkit-core/src/response-cache/tiers.test.ts b/packages/toolkit-core/src/response-cache/tiers.test.ts index 0c4dd0085..aba16a91b 100644 --- a/packages/toolkit-core/src/response-cache/tiers.test.ts +++ b/packages/toolkit-core/src/response-cache/tiers.test.ts @@ -34,6 +34,14 @@ describe("classifyUrl", () => { ).toBe("volatile"); }); + it("keeps project events volatile when adjacent events are collapsed", () => { + expect( + classifyUrl( + `${API}/projects/acme/backend/events/deadbeef/?collapse=adjacentEvents`, + ), + ).toBe("volatile"); + }); + it("reuses full traces for at most 60 seconds, since spans can still arrive", () => { const url = `${API}/organizations/acme/trace/${TRACE_ID}/?limit=100`; expect(classifyUrl(url)).toBe("volatile"); diff --git a/packages/toolkit-core/src/response-cache/tiers.ts b/packages/toolkit-core/src/response-cache/tiers.ts index 321836f9f..4ad9b72a7 100644 --- a/packages/toolkit-core/src/response-cache/tiers.ts +++ b/packages/toolkit-core/src/response-cache/tiers.ts @@ -49,8 +49,9 @@ const URL_TIER_PATTERNS: readonly [TtlTier, readonly RegExp[]][] = [ /\/trace-logs\//, // Full traces gain spans as they arrive /\/trace\/[0-9a-f]{32}\//, - // Project event details embed `nextEventID`/`previousEventID` and user - // reports, and reprocessing can change them for the same ID + // Project event details embed user reports (and `nextEventID`/ + // `previousEventID` unless collapsed), and reprocessing can change them + // for the same ID /\/projects\/[^/]+\/[^/]+\/events\/[^/?]+\/?(?:\?|$)/, ], ], From 471694e6670372f0905376b24970e0a98cd6c48e Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Thu, 29 Oct 2026 11:24:05 +0000 Subject: [PATCH 2/2] test(cli): Drop collapse assertions that only test the @sentry/api default --- packages/cli/test/lib/api-client.coverage.test.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/cli/test/lib/api-client.coverage.test.ts b/packages/cli/test/lib/api-client.coverage.test.ts index 3c479b198..fd19c3f93 100644 --- a/packages/cli/test/lib/api-client.coverage.test.ts +++ b/packages/cli/test/lib/api-client.coverage.test.ts @@ -1006,9 +1006,6 @@ describe("events.ts", () => { const req = new Request(input!, init); expect(req.url).toContain("/organizations/test-org/issues/"); expect(req.url).toContain("/events/latest/"); - expect(new URL(req.url).searchParams.getAll("collapse")).toEqual([ - "adjacentEvents", - ]); return new Response(JSON.stringify(event), { status: 200, headers: { "Content-Type": "application/json" }, @@ -1029,9 +1026,6 @@ describe("events.ts", () => { expect(req.url).toContain( "/projects/test-org/test-project/events/evt-abc/", ); - expect(new URL(req.url).searchParams.getAll("collapse")).toEqual([ - "adjacentEvents", - ]); return new Response(JSON.stringify(event), { status: 200, headers: { "Content-Type": "application/json" },