From 42fa6c159c30ae469940a3a4beaa303c8d851b1f Mon Sep 17 00:00:00 2001 From: dualfroz Date: Sat, 17 Oct 2026 04:21:20 +0200 Subject: [PATCH] fix(issues): Escape reserved tag keys in tag drawer value links Clicking a value in the tag details drawer built the search as `key:"value"` with the raw tag key. For a custom tag named after a reserved search key, like `project_id`, the events page searched the built-in field instead of the tag and errored. Escape the key with `escapeIssueTagKey`, which the value actions menu in the same file already uses, so the link becomes `tags[project_id]:"value"`. --- .../tagDetailsDrawerContent.spec.tsx | 46 +++++++++++++++++++ .../groupTags/tagDetailsDrawerContent.tsx | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/static/app/views/issueDetails/groupTags/tagDetailsDrawerContent.spec.tsx b/static/app/views/issueDetails/groupTags/tagDetailsDrawerContent.spec.tsx index 2193f10..0decfcc 100644 --- a/static/app/views/issueDetails/groupTags/tagDetailsDrawerContent.spec.tsx +++ b/static/app/views/issueDetails/groupTags/tagDetailsDrawerContent.spec.tsx @@ -437,6 +437,52 @@ describe('TagDetailsDrawerContent', () => { expect(await screen.findByText('id:123')).toBeInTheDocument(); }); + it('escapes reserved tag keys in the tag value link', async () => { + const projectIdTag: TagWithTopValues = { + key: 'project_id', + name: 'Project_id', + totalValues: 3, + uniqueValues: 1, + topValues: [ + { + count: 3, + name: '42', + value: '42', + key: 'project_id', + lastSeen: '2024-01-01T00:00:00Z', + firstSeen: '2024-01-01T00:00:00Z', + }, + ], + }; + + MockApiClient.addMockResponse({ + url: '/organizations/org-slug/issues/1/tags/project_id/', + body: projectIdTag, + }); + MockApiClient.addMockResponse({ + url: '/organizations/org-slug/issues/1/tags/project_id/values/', + body: [ + { + count: 3, + firstSeen: '2024-01-01T00:00:00Z', + lastSeen: '2024-01-01T00:00:00Z', + name: '42', + value: '42', + key: 'project_id', + }, + ], + }); + + render(, { + initialRouterConfig: makeInitialRouterConfig('project_id'), + }); + + expect(await screen.findByRole('link', {name: '42'})).toHaveAttribute( + 'href', + '/organizations/org-slug/issues/1/events/recommended/?query=tags%5Bproject_id%5D%3A%2242%22' + ); + }); + it('renders empty tag value label and hides copy action', async () => { const makeTopValue = (value: string, count: number) => ({ count, diff --git a/static/app/views/issueDetails/groupTags/tagDetailsDrawerContent.tsx b/static/app/views/issueDetails/groupTags/tagDetailsDrawerContent.tsx index 04770ad..95cdc3a 100644 --- a/static/app/views/issueDetails/groupTags/tagDetailsDrawerContent.tsx +++ b/static/app/views/issueDetails/groupTags/tagDetailsDrawerContent.tsx @@ -186,7 +186,7 @@ function TagDetailsRow({ query: undefined, } : { - query: tagValue.query || `${key}:"${tagValue.value}"`, + query: tagValue.query || `${escapeIssueTagKey(key)}:"${tagValue.value}"`, }; const allEventsLocation = {