Skip to content

feat(core): add stringify helper and make AI-tracing serializers safe#22163

Draft
logaretm wants to merge 1 commit into
developfrom
feat/consolidate-safe-json-stringify
Draft

feat(core): add stringify helper and make AI-tracing serializers safe#22163
logaretm wants to merge 1 commit into
developfrom
feat/consolidate-safe-json-stringify

Conversation

@logaretm

@logaretm logaretm commented Jul 9, 2026

Copy link
Copy Markdown
Member

Adds an exported stringify to @sentry/core and routes the SDK's "serialize a value for a span attribute" helpers through it.

stringify coerces a value to a string without ever throwing: strings pass through unchanged (so an already-serialized value isn't double-encoded and a plain string like a model name isn't wrapped in quotes), anything else is JSON.stringify-ed, and a circular ref or BigInt yields '[unserializable]' rather than throwing. It's a stringify, not a JSON-stringify, which is why strings aren't quoted.

The real motivation is a latent bug: getJsonString and getTruncatedJsonString threw on circular refs / BigInt, and every call site feeds their result straight into span.setAttribute with no try/catch. So a non-serializable value in an LLM message (tool args, usage metadata, etc.) could throw out of the instrumentation hook and disrupt the wrapped call.

Consolidates safeStringify (server-utils) and langchain's private asString into stringify, deletes the throwing internal getJsonString (its 8 call sites now use the safe helper), and wraps getTruncatedJsonString in a try/catch. Note the throw there can also originate in the media-stripping/truncation step, not just JSON.stringify, so the try/catch covers the whole non-string path. Success paths are unchanged.

@logaretm logaretm changed the title feat(core): add safeJsonStringify and make AI-tracing serializers safe feat(core): add safeJsonStringify and normalize usage Jul 9, 2026
Adds an exported stringify to core (string passthrough, else JSON.stringify, never throws)
and routes the SDK's span-attribute serializers through it. getJsonString and
getTruncatedJsonString previously threw on circular refs / BigInt straight into
span.setAttribute with no try/catch, which could crash instrumentation; the safe path
returns '[unserializable]' instead. Consolidates safeStringify (server-utils) and langchain's
asString too.
@logaretm logaretm force-pushed the feat/consolidate-safe-json-stringify branch from b4c66d5 to 2d78382 Compare July 9, 2026 20:09
@logaretm logaretm changed the title feat(core): add safeJsonStringify and normalize usage feat(core): add stringify helper and make AI-tracing serializers safe Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 27.59 kB - -
@sentry/browser - with treeshaking flags 26.03 kB - -
@sentry/browser (incl. Tracing) 46.34 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 48.13 kB - -
@sentry/browser (incl. Tracing, Profiling) 51.12 kB - -
@sentry/browser (incl. Tracing, Replay) 85.62 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 75.26 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 90.32 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 102.97 kB - -
@sentry/browser (incl. Feedback) 44.76 kB - -
@sentry/browser (incl. sendFeedback) 32.38 kB - -
@sentry/browser (incl. FeedbackAsync) 37.51 kB - -
@sentry/browser (incl. Metrics) 28.67 kB - -
@sentry/browser (incl. Logs) 28.91 kB - -
@sentry/browser (incl. Metrics & Logs) 29.59 kB - -
@sentry/react 29.38 kB - -
@sentry/react (incl. Tracing) 48.61 kB - -
@sentry/vue 33.02 kB - -
@sentry/vue (incl. Tracing) 48.31 kB - -
@sentry/svelte 27.61 kB - -
CDN Bundle 30 kB - -
CDN Bundle (incl. Tracing) 48.32 kB - -
CDN Bundle (incl. Logs, Metrics) 31.57 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.64 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 70.81 kB - -
CDN Bundle (incl. Tracing, Replay) 85.84 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 87.14 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 91.64 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.92 kB - -
CDN Bundle - uncompressed 89.35 kB - -
CDN Bundle (incl. Tracing) - uncompressed 146.1 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 94.05 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 150.07 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 218.78 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 265.3 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 269.26 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 279 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 282.95 kB - -
@sentry/nextjs (client) 51.16 kB - -
@sentry/sveltekit (client) 46.78 kB - -
@sentry/core/server 78.48 kB +0.07% +48 B 🔺
@sentry/core/browser 64.81 kB +0.08% +49 B 🔺
@sentry/node-core 62.72 kB - -
@sentry/node 125.36 kB -0.02% -18 B 🔽
@sentry/node (incl. diagnostics channel injection) 138.56 kB +0.01% +4 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 69.95 kB - -
@sentry/node/light 50.72 kB +0.01% +1 B 🔺
@sentry/node - without tracing 74.06 kB +0.01% +1 B 🔺
@sentry/aws-serverless 83.25 kB -0.01% -1 B 🔽
@sentry/cloudflare (withSentry) - minified 181.71 kB - -
@sentry/cloudflare (withSentry) 449.16 kB - -

View base workflow run

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.

1 participant