Skip to content

Commit 03df3fb

Browse files
s1gr1dchargomeclaude
authored
feat(core)!: Remove sendDefaultPii in favor of dataCollection (#22918)
Removes all occurrences of `sendDefaultPii` and also updates the migration docs. Closes #22708 --------- Co-authored-by: Charly Gomez <charly.gomez1310@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 7a86f15 commit 03df3fb

27 files changed

Lines changed: 131 additions & 224 deletions

File tree

.agents/skills/add-ai-integration/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ Reference: `packages/node/src/integrations/tracing/langchain/`
9595

9696
## Key Rules
9797

98-
1. Respect `sendDefaultPii` for `recordInputs`/`recordOutputs`
98+
1. Respect `dataCollection.genAI` for recording input and output messages
9999
2. Set `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.{provider}'` (alphanumerics, `_`, `.` only)
100100
3. Truncate large data with helper functions from `utils.ts`
101101
4. `gen_ai.invoke_agent` for parent ops, `gen_ai.chat` for child ops

MIGRATION.md

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -96,64 +96,64 @@ For most users, day-to-day tracing is **unchanged**.
9696

9797
Affected SDKs: All SDKs.
9898

99-
The `sendDefaultPii` option was **removed** and replaced by a more granular `dataCollection` option that controls each category of collected data individually.
99+
> **Heads up — this is a behavior change, not just a renamed option.**
100+
> In v10, leaving `sendDefaultPii` unset behaved like `sendDefaultPii: false` (restrictive).
101+
> In v11, leaving `dataCollection` unset collects the categories below **by default**.
102+
> Review this before upgrading if you'd rather not collect HTTP request data, database queries, or GenAI inputs/outputs.
100103
101-
The **default behaviour is now more permissive**. In v10, with neither `sendDefaultPii` nor `dataCollection` set, the SDK behaved like `sendDefaultPii: false`. In v11, the `dataCollection` defaults apply out of the box:
104+
We've replaced `sendDefaultPii` with `dataCollection`, which controls each category of collected data individually. The default is now more permissive than in v10.
102105

103-
| Category | v10 default (no `sendDefaultPii`) | v11 default |
104-
| --------------------- | --------------------------------- | -------------------- |
105-
| `userInfo` | `false` | `true` |
106-
| `cookies` | sensitive keys denied | `true` |
107-
| `httpHeaders` | sensitive keys denied | request + response |
108-
| `httpBodies` | none (`[]`) | all request/response |
109-
| `urlQueryParams` | sensitive keys denied | `true` |
110-
| `genAI` | inputs/outputs off | inputs + outputs on |
111-
| `stackFrameVariables` | `true` | `true` |
112-
| `frameContextLines` | `5` | `5` |
106+
| Category | v10 default (`sendDefaultPii` off) | v11 default |
107+
| --------------------- | ---------------------------------- | -------------------- |
108+
| `userInfo` | `false` | `true` |
109+
| `cookies` | not collected | `true` |
110+
| `httpHeaders` | request + response, PII scrubbed | request + response |
111+
| `httpBodies` | not collected (size only) | all request/response |
112+
| `urlQueryParams` | `true` | `true` |
113+
| `genAI` | inputs + outputs not collected | inputs + outputs |
114+
| `databaseQueryData` | `false` | `true` |
115+
| `stackFrameVariables` | `true` | `true` |
116+
| `frameContextLines` | `7` | `5` |
113117

114-
> Sensitive values (keys, tokens, auth headers, etc.) are always filtered out regardless of these settings.
118+
> Sentry's built-in sensitive-data filtering still applies. Review your data-scrubbing config for categories that may contain sensitive values — especially request/response bodies.
115119
116-
Migration:
120+
#### If you previously set `sendDefaultPii: true`
121+
122+
The v11 default matches this, so just remove the option:
117123

118124
```js
119-
// before (v10) — collect the default set of PII
120-
Sentry.init({
121-
sendDefaultPii: true,
122-
});
125+
// v10
126+
Sentry.init({ sendDefaultPii: true });
123127

124-
// after (v11) — this is now the default; you can remove the option entirely,
125-
// or opt into specific categories explicitly:
126-
Sentry.init({
127-
dataCollection: {
128-
userInfo: true,
129-
cookies: true,
130-
httpHeaders: { request: true, response: true },
131-
urlQueryParams: true,
132-
genAI: { inputs: true, outputs: true },
133-
},
134-
});
128+
// v11 — same behavior is now the default
129+
Sentry.init({});
135130
```
136131

137-
If you previously relied on the restrictive default (`sendDefaultPii: false` or unset) and want to
138-
keep collecting as little data as possible, you now need to opt out explicitly:
132+
#### If you want to keep the v10 default behavior
133+
134+
Set the baseline explicitly. **Don't leave `dataCollection` unset** — that now enables broader collection.
139135

140136
```js
141-
// after (v11)restrict data collection to the v10-like minimum
137+
// v11 — preserves the v10 default
142138
Sentry.init({
143139
dataCollection: {
144140
userInfo: false,
145141
cookies: false,
146-
httpHeaders: { request: false, response: false },
142+
httpHeaders: { deny: ['forwarded', '-ip', 'remote-', 'via', '-user'] },
147143
httpBodies: [],
148-
urlQueryParams: false,
144+
urlQueryParams: { deny: ['forwarded', '-ip', 'remote-', 'via', '-user'] },
149145
genAI: { inputs: false, outputs: false },
146+
databaseQueryData: false,
147+
graphQL: { document: false, variables: false },
150148
},
151149
});
152150
```
153151

154152
Each key-value field (`cookies`, `urlQueryParams`, `httpHeaders.request`, `httpHeaders.response`) accepts
155153
`true`, `false`, `{ allow: string[] }`, or `{ deny: string[] }` for fine-grained control.
156154

155+
See the [`dataCollection` docs](https://docs.sentry.io/platforms/javascript/configuration/options/#dataCollection) for the full option list.
156+
157157
#### RequestData
158158

159159
The `requestDataIntegration`'s `include` options remain an integration-level override. An explicit `false`

dev-packages/e2e-tests/test-applications/nextjs-16-streaming-cacheComponents/instrumentation-client.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ Sentry.init({
55
dsn: process.env.NEXT_PUBLIC_E2E_TEST_DSN,
66
tunnel: `http://localhost:3031/`, // proxy server
77
tracesSampleRate: 1.0,
8-
sendDefaultPii: true,
98
integrations: [Sentry.spanStreamingIntegration()],
109
});
1110

dev-packages/e2e-tests/test-applications/nextjs-16-streaming-cacheComponents/sentry.edge.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ Sentry.init({
55
dsn: process.env.NEXT_PUBLIC_E2E_TEST_DSN,
66
tunnel: `http://localhost:3031/`, // proxy server
77
tracesSampleRate: 1.0,
8-
sendDefaultPii: true,
98
traceLifecycle: 'stream',
109
integrations: [Sentry.spanStreamingIntegration()],
1110
});

dev-packages/e2e-tests/test-applications/nextjs-16-streaming-cacheComponents/sentry.server.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ Sentry.init({
55
dsn: process.env.NEXT_PUBLIC_E2E_TEST_DSN,
66
tunnel: `http://localhost:3031/`, // proxy server
77
tracesSampleRate: 1.0,
8-
sendDefaultPii: true,
98
traceLifecycle: 'stream',
109
integrations: [Sentry.vercelAIIntegration(), Sentry.spanStreamingIntegration()],
1110
});

dev-packages/node-integration-tests/suites/tracing/requestData-streamed/instrument.mjs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,4 @@ Sentry.init({
77
tracesSampleRate: 1.0,
88
transport: loggingTransport,
99
traceLifecycle: 'stream',
10-
// todo(v11): bridge-regression counterpart to instrument-with-datacollection.mjs; remove when sendDefaultPii is dropped in v11
11-
sendDefaultPii: true,
1210
});

packages/astro/src/server/middleware.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ async function instrumentRequestStartHttpServerSpan(
175175
}
176176

177177
const request = ctx.request;
178+
const client = getClient();
179+
if (!client) {
180+
return next();
181+
}
178182

179183
// Note: We guard outside of this function call that the request is dynamic
180184
// accessing headers on a static route would throw
@@ -212,10 +216,7 @@ async function instrumentRequestStartHttpServerSpan(
212216
method,
213217
[URL_FULL]: ctx.url.href,
214218
[URL_PATH]: ctx.url.pathname,
215-
...httpHeadersToSpanAttributes(
216-
winterCGHeadersToDict(request.headers),
217-
getClient()?.getDataCollectionOptions() ?? false,
218-
),
219+
...httpHeadersToSpanAttributes(winterCGHeadersToDict(request.headers), client.getDataCollectionOptions()),
219220
};
220221

221222
if (parametrizedRoute) {

packages/bun/src/integrations/bunserver.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,9 @@ function wrapRequestHandler<T extends RouteHandler = RouteHandler>(
221221
const client = getClient();
222222
const dataCollection = client?.getDataCollectionOptions();
223223

224-
Object.assign(attributes, httpHeadersToSpanAttributes(request.headers.toJSON(), dataCollection));
224+
if (dataCollection) {
225+
Object.assign(attributes, httpHeadersToSpanAttributes(request.headers.toJSON(), dataCollection));
226+
}
225227

226228
isolationScope.setSDKProcessingMetadata({
227229
normalizedRequest: {
@@ -254,7 +256,11 @@ function wrapRequestHandler<T extends RouteHandler = RouteHandler>(
254256
status_code: response.status,
255257
});
256258

257-
span.setAttributes(httpHeadersToSpanAttributes(response.headers.toJSON(), dataCollection, 'response'));
259+
if (dataCollection) {
260+
span.setAttributes(
261+
httpHeadersToSpanAttributes(response.headers.toJSON(), dataCollection, 'response'),
262+
);
263+
}
258264
}
259265
return response;
260266
} catch (e) {

packages/cloudflare/src/baseSdk.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ export function getBaseDefaultIntegrations(options: CloudflareOptions): Integrat
6060
linkedErrorsIntegration(),
6161
fetchIntegration(),
6262
httpServerIntegration(),
63-
// oxlint-disable-next-line typescript/no-deprecated
6463
requestDataIntegration(),
6564
consoleIntegration(),
6665
// The orchestrion diagnostics-channel subscribers (mysql, pg, …). The

packages/cloudflare/src/request.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import type { CfProperties, IncomingRequestCfProperties } from '@cloudflare/work
22
import {
33
captureException,
44
continueTrace,
5-
getClient,
65
getHttpSpanDetailsFromUrlObject,
76
httpHeadersToSpanAttributes,
87
parseStringToURLObject,
@@ -100,13 +99,12 @@ export function wrapRequestHandlerWithInit(
10099
attributes['user_agent.original'] = userAgentHeader;
101100
}
102101

103-
Object.assign(
104-
attributes,
105-
httpHeadersToSpanAttributes(
106-
winterCGHeadersToDict(request.headers),
107-
getClient()?.getDataCollectionOptions() ?? false,
108-
),
109-
);
102+
if (client) {
103+
Object.assign(
104+
attributes,
105+
httpHeadersToSpanAttributes(winterCGHeadersToDict(request.headers), client.getDataCollectionOptions()),
106+
);
107+
}
110108

111109
attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] = 'http.server';
112110

0 commit comments

Comments
 (0)