Skip to content

fix(core): Set http header span attributes as string arrays - #24231

Open
Lms24 wants to merge 2 commits into
developfrom
lms/http-header-attributes-as-arrays
Open

fix(core): Set http header span attributes as string arrays#24231
Lms24 wants to merge 2 commits into
developfrom
lms/http-header-attributes-as-arrays

Conversation

@Lms24

@Lms24 Lms24 commented Sep 9, 2026

Copy link
Copy Markdown
Member

Follow-up to #24222: httpHeadersToSpanAttributes now sets http.request.header.<key> / http.response.header.<key> as Array<string> instead of string`. This aligns SDK behaviour with the type specified in sentry and otel conventions.

Notes:

  • Cookie attributes (http.request.header.cookie.<name>, set-cookie.<name>) stay single strings. A bit of a divergence from conventions but I think this should be fine, given this attribute doesn't fully fit the key pattern in conventions. probably worth adding a dedicated entry for this attribute in conventions. A cookie has exactly one value, so no need for an array here.
  • packages/browser's httpContext integration writes http.request.header.referer itself (it deliberately doesn't use the core util, for bundle size). It's included here so it isn't the one header attribute left as a string.

@Lms24
Lms24 added this pull request to stack #24232 September 9, 2026 09:58
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 28.92 kB +0.41% +117 B 🔺
@sentry/browser - with treeshaking flags 27.21 kB +0.4% +107 B 🔺
@sentry/browser - with treeshaking flags tracing without tracing 27.11 kB +0.38% +100 B 🔺
@sentry/browser (incl. Tracing) 50.28 kB +2.17% +1.06 kB 🔺
@sentry/browser (incl. Tracing + Span Streaming) 50.28 kB +2.17% +1.07 kB 🔺
@sentry/browser (incl. Tracing, Profiling) 53.27 kB +2.19% +1.14 kB 🔺
@sentry/browser (incl. Tracing, Replay) 89.77 kB +1.14% +1.01 kB 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 78.86 kB +1.17% +911 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 94.46 kB +1.09% +1.02 kB 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 107.47 kB +1.03% +1.09 kB 🔺
@sentry/browser (incl. Feedback) 46.42 kB +0.26% +118 B 🔺
@sentry/browser (incl. sendFeedback) 33.97 kB +0.32% +105 B 🔺
@sentry/browser (incl. FeedbackAsync) 39.08 kB +0.27% +103 B 🔺
@sentry/browser (incl. Metrics) 29.93 kB +0.38% +112 B 🔺
@sentry/browser (incl. Logs) 30.19 kB +0.36% +108 B 🔺
@sentry/browser (incl. Metrics & Logs) 30.87 kB +0.39% +119 B 🔺
@sentry/react 30.67 kB +0.4% +122 B 🔺
@sentry/react (incl. Tracing) 52.6 kB +2.02% +1.04 kB 🔺
@sentry/vue 36.16 kB +0.3% +106 B 🔺
@sentry/vue (incl. Tracing) 52.53 kB +2.06% +1.06 kB 🔺
@sentry/svelte 28.93 kB +0.34% +98 B 🔺
CDN Bundle 30.65 kB +0.33% +99 B 🔺
CDN Bundle (incl. Tracing) 50.78 kB +2.11% +1.05 kB 🔺
CDN Bundle (incl. Logs, Metrics) 32.92 kB +0.32% +105 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 52.74 kB +2.01% +1.04 kB 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 73.62 kB +0.2% +141 B 🔺
CDN Bundle (incl. Tracing, Replay) 88.33 kB +1.19% +1.04 kB 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 90.29 kB +1.25% +1.11 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 94.37 kB +1.24% +1.15 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 96.38 kB +1.24% +1.18 kB 🔺
CDN Bundle - uncompressed 90.73 kB +0.31% +272 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 151.69 kB +2.38% +3.52 kB 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 97.31 kB +0.29% +281 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 157.66 kB +2.29% +3.52 kB 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 226.72 kB +0.2% +432 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 271.26 kB +1.31% +3.5 kB 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 277.21 kB +1.29% +3.5 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 284.97 kB +1.25% +3.5 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 290.91 kB +1.22% +3.5 kB 🔺
@sentry/nextjs (client) 54.92 kB +1.71% +921 B 🔺
@sentry/sveltekit (client) 50.7 kB +2.12% +1.05 kB 🔺
@sentry/core/server 37.08 kB +0.27% +97 B 🔺
@sentry/core/browser 13.66 kB +0.82% +110 B 🔺
@sentry/node 128.42 kB +0.5% +630 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 81.82 kB +0.26% +205 B 🔺
@sentry/node - without tracing 89.03 kB +0.36% +315 B 🔺
@sentry/node - without channel injection 107.53 kB +0.47% +502 B 🔺
@sentry/aws-serverless 97.41 kB +0.33% +312 B 🔺
@sentry/cloudflare (withSentry) - minified 203.01 kB +0.52% +1.03 kB 🔺
@sentry/cloudflare (withSentry) 505.44 kB +0.55% +2.76 kB 🔺

View base workflow run

@Lms24 Lms24 self-assigned this Sep 9, 2026
@Lms24
Lms24 marked this pull request as ready for review September 9, 2026 10:33
@Lms24
Lms24 requested review from a team as code owners September 9, 2026 10:33
@Lms24
Lms24 requested review from JPeer264, logaretm, mydea and nicohrubec and removed request for a team September 9, 2026 10:33
@@ -310,25 +310,26 @@ export function httpHeadersToSpanAttributes(
spanAttributes[`${prefix}${lowerKey}.${cookieKey}`] = cookieValue;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because you mentioned the "cookie extra case" - that's this line, right?

If we keep that, we should probably add http.request.header.cookie.<key> and http.response.header.set-cookie.<key> to conventions. I would keep it as a string as it's just a string value:

http.request.header.cookie.session_id = "abc123"
http.request.header.cookie.theme      = "dark"

If we want to stay fully convention-conforming, we could save the cookie as a string array as we don't need the extra per-cookie key anymore with string arrays:

http.request.header.cookie     = ["session_id=abc123; theme=dark"]
http.response.header.set-cookie = ["session_id=abc123", "theme=dark; Path=/"]

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After talking a bit about this within the team and confirming scrubbing behaviour with Ingest, we'll go with leaving the cookie headers as-is. I'm gonna add new attributes to conventions to cover these attributes explicitly to document the slight divergence from the http.request.header .<key>: string[] pattern.

@Lms24
Lms24 force-pushed the lms/http-header-attributes-as-arrays branch from 0ab5c18 to cfd419b Compare September 10, 2026 10:37
Comment on lines 310 to +313
spanAttributes[`${prefix}${lowerKey}.${cookieKey}`] = cookieValue;
}
} else {
spanAttributes[`${prefix}${lowerKey}`] = FILTERED_VALUE;
spanAttributes[`${prefix}${lowerKey}`] = [FILTERED_VALUE];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Malformed cookie headers are set as an array ['[Filtered]'], but the PR description states they should be single strings, creating a type inconsistency for span attributes.
Severity: MEDIUM

Suggested Fix

To ensure type consistency as described in the PR, change the assignment for filtered malformed cookie headers from an array to a single string. Modify line 313 from spanAttributes[...]= [FILTERED_VALUE] to spanAttributes[...] = FILTERED_VALUE.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: packages/core/src/utils/request.ts#L310-L313

Potential issue: The code at `request.ts:313` handles malformed or empty `Cookie`
headers by setting the corresponding span attribute to `[FILTERED_VALUE]`, which is an
array. This contradicts the PR's stated goal that "Cookie attributes ... stay single
strings". While correctly parsed cookies result in string attributes, this special case
for malformed headers introduces a type inconsistency. Downstream consumers expecting
only string values for cookie-related attributes may fail when encountering an array in
these edge-case scenarios, which can occur with custom clients or proxies.

Did we get this right? 👍 / 👎 to inform future reviews.

@Lms24
Lms24 force-pushed the lms/http-header-attributes-as-arrays branch from cfd419b to b2eb726 Compare September 10, 2026 11:07

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b2eb726. Configure here.

Comment thread packages/core/src/utils/request.ts
Base automatically changed from lms/fix-core-http-header-normalization to develop September 10, 2026 13:15
Lms24 and others added 2 commits September 10, 2026 15:15
`httpHeadersToSpanAttributes` now writes `http.request.header.<key>` /
`http.response.header.<key>` as a string array instead of a single string.
Headers sent multiple times previously got their values joined with `;`,
which lost the boundaries between values; each value is now its own array
entry.

This matches the Sentry/OTel semantic conventions and the shape the
outgoing-fetch (undici) instrumentation already emits for the same
attributes. `packages/browser`'s `httpContext` integration is updated too,
so `http.request.header.referer` isn't the one header attribute left as a
string. Cookie attributes (`http.request.header.cookie.<name>`) stay
single strings, as a cookie only ever has one value.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Lms24
Lms24 force-pushed the lms/http-header-attributes-as-arrays branch from b2eb726 to a71135a Compare September 10, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants