From 7f2369ba5752a370cbe126f5e3b0d37dc8253538 Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 18:19:26 +0000 Subject: [PATCH] fix(cli): Accept user.display as a replay explore field `sentry explore --dataset replays --field user.display` failed with a ValidationError because the replay field map had no user.display entry (CLI-1EZ). Agents reach for it because Discover datasets support it. Resolve it to the same user label the replay list shows and request the user root field from the API. Ported from getsentry/cli#1639. Co-Authored-By: BYK --- packages/cli/src/lib/replay-search.ts | 2 ++ packages/cli/test/lib/replay-search.test.ts | 27 +++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/packages/cli/src/lib/replay-search.ts b/packages/cli/src/lib/replay-search.ts index ae5665d39..8a85151ca 100644 --- a/packages/cli/src/lib/replay-search.ts +++ b/packages/cli/src/lib/replay-search.ts @@ -129,6 +129,7 @@ const REPLAY_FIELD_RESOLVERS: Record = { url: (replay) => firstValue(replay.urls), urls: (replay) => replay.urls, user: (replay) => getReplayUserLabel(replay), + "user.display": (replay) => getReplayUserLabel(replay), "user.email": (replay) => replay.user?.email, "user.geo.city": (replay) => replay.user?.geo?.city, "user.geo.country_code": (replay) => replay.user?.geo?.country_code, @@ -176,6 +177,7 @@ function replayRequestRoot(field: string): string { case "trace": case "trace_id": return "trace_ids"; + case "user.display": case "user.email": case "user.geo.city": case "user.geo.country_code": diff --git a/packages/cli/test/lib/replay-search.test.ts b/packages/cli/test/lib/replay-search.test.ts index 73eb819c9..d95942c5c 100644 --- a/packages/cli/test/lib/replay-search.test.ts +++ b/packages/cli/test/lib/replay-search.test.ts @@ -1,5 +1,6 @@ import { describe, expect, test } from "vitest"; import { + getReplayFieldValue, getReplayRequestFields, isSupportedReplayField, } from "../../src/lib/replay-search.js"; @@ -37,4 +38,30 @@ describe("isSupportedReplayField", () => { test("does not expose replay detail-only fields in replay explore", () => { expect(isSupportedReplayField("replay_type")).toBe(false); }); + + test("recognizes user.display as a supported replay field", () => { + expect(isSupportedReplayField("user.display")).toBe(true); + }); +}); + +describe("getReplayRequestFields", () => { + test("maps user.display to the user API root field", () => { + expect(getReplayRequestFields(["user.display"])).toEqual(["id", "user"]); + }); +}); + +describe("getReplayFieldValue", () => { + test("resolves user.display to the best available user label", () => { + const replay = { + id: "abc123", + user: { + display_name: "Jane Doe", + username: "jane", + email: "jane@example.com", + id: "1", + ip: "1.2.3.4", + }, + } as Parameters[0]; + expect(getReplayFieldValue(replay, "user.display")).toBe("Jane Doe"); + }); });