The RUM SDK flattens an Error's cause chain into error.causes[{ message, type, stack }] and sends it. beforeSend rewrites only message, stack, handling_stack, and resource.url — nothing walks causes.
So a cause's message or stack bypasses every layer we have: redactErrorText, redactCredentialParams, and the relayed-message type gate alike.
Where a cause is attached today
src/integrations/api/sse/streamOperation.ts throws with one twice:
:75 — new SSEUnsupportedError('Failed to open the SSE stream.', { cause: error })
:121 — new SSEInconclusiveError('The stream went idle before completing.', { cause: error })
In both, the cause is the underlying fetch/transport error. Its text is not customer input, so this is a structural gap rather than a known leak — but it is the one path where redaction has no coverage at all, and any future { cause } on an error that does carry server or user text would be published unredacted with nothing to catch it.
Scale
Zero events carrying error.causes in the last 7 days of production RUM. Filed as defense-in-depth, not an active exposure.
Suggested direction
Walk causes[] in beforeSend and apply the same treatment each entry's message/stack already gets at the top level — including the relayed-type check, so a cause of a relayed error is withheld too.
Related
Found by the cross-model pre-push review of the PR that added the relayed-message type gate; scoped pre-existing and outside that diff.
The RUM SDK flattens an
Error'scausechain intoerror.causes[{ message, type, stack }]and sends it.beforeSendrewrites onlymessage,stack,handling_stack, andresource.url— nothing walkscauses.So a cause's message or stack bypasses every layer we have:
redactErrorText,redactCredentialParams, and the relayed-message type gate alike.Where a cause is attached today
src/integrations/api/sse/streamOperation.tsthrows with one twice::75—new SSEUnsupportedError('Failed to open the SSE stream.', { cause: error }):121—new SSEInconclusiveError('The stream went idle before completing.', { cause: error })In both, the cause is the underlying fetch/transport error. Its text is not customer input, so this is a structural gap rather than a known leak — but it is the one path where redaction has no coverage at all, and any future
{ cause }on an error that does carry server or user text would be published unredacted with nothing to catch it.Scale
Zero events carrying
error.causesin the last 7 days of production RUM. Filed as defense-in-depth, not an active exposure.Suggested direction
Walk
causes[]inbeforeSendand apply the same treatment each entry'smessage/stackalready gets at the top level — including the relayed-type check, so a cause of a relayed error is withheld too.Related
Found by the cross-model pre-push review of the PR that added the relayed-message type gate; scoped pre-existing and outside that diff.