Skip to content

[dop] [error-tracking]: derive debug_id from file content - #470

Open
jhssilva wants to merge 3 commits into
masterfrom
hugo.silva/fix-debug-id-key-path
Open

[dop] [error-tracking]: derive debug_id from file content#470
jhssilva wants to merge 3 commits into
masterfrom
hugo.silva/fix-debug-id-key-path

Conversation

@jhssilva

@jhssilva jhssilva commented Jul 28, 2026

Copy link
Copy Markdown

Summary

The RUM plugin injects a debug_id into every built chunk's own JS content. This PR makes the error-tracking plugin extract that debug_id back out of each file when it uploads that file's sourcemap, instead of relying on the previous filename-based coordination between the two plugins.

Why

Previously, error-tracking got the debug_id from a side-channel Map that the RUM plugin populated at injection time, keyed by the chunk's filename. Bundlers (webpack/rspack) rename chunks after injection via realContentHash, so by the time error-tracking looked the value up by the chunk's final filename, the key no longer matched — the debug_id was silently dropped for almost every chunk in a real build.

How

Instead of coordinating through a filename-keyed Map, error-tracking now reads each minified file's own content directly and extracts the debug_id from the ddDebugId literal the RUM plugin already embeds inside it. This works no matter what renaming the bundler does afterward, since the debug_id travels with the file's content, not its name.

  • error-tracking/src/sourcemaps/debugId.ts (new): extractDebugId() — regex-extracts the debug_id from a file's content.
  • error-tracking/src/sourcemaps/sender.ts: reads the minified file's content and extracts the debug_id from it, in place of the old Map lookup.
  • plugins/rum/src/index.ts + getSourceCodeContextSnippet.ts: RUM no longer needs to track debug_ids separately — the value already lives in the code it injects.
  • core/src/helpers/fs.ts: new readFilePrefix() helper, since we only need the first bytes of each file, not the whole thing.
  • plugins/injection/{xpack,esbuild}.ts: keep injected chunk filenames as relative paths for consistency with the rest of the pipeline.

Notes

  • Real end-to-end build against a module-federation-remote entry (mf_apm_runtime_app, rspack), uploaded to staging: each nested chunk's uploaded debug_id matches the ddDebugId literal embedded in that chunk's own file.

@jhssilva
jhssilva requested review from a team as code owners July 28, 2026 17:28
@jhssilva
jhssilva requested review from aananiadis and removed request for a team July 28, 2026 17:28
@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jul 28, 2026

Copy link
Copy Markdown

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 6ebf91f | Docs | Datadog PR Page | Give us feedback!

// but the content, and the debug_id embedded in it, is unaffected. Only the file's
// prefix is read, since the RUM plugin's injected snippet always lands near the
// start of the file (see DEBUG_ID_SEARCH_PREFIX_BYTES).
const fileContent = await readFilePrefix(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: With esbuild, this runs before the injection onEnd, so it uploads the pre-injection files without ddDebugId. Should't we defer the upload until injection completes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

For now, we'll be dogfooding in web-ui. We'll do other iterations as needed in future pr's.
We'll keep this in mind.

Comment thread packages/core/src/helpers/fs.ts Outdated
@jhssilva
jhssilva changed the base branch from buranmert/rum-debug-id-to-error-tracking to master July 31, 2026 15:03
@jhssilva jhssilva changed the title fix(error-tracking): derive debug_id from file content, not a filename Map [dop] [error-tracking]: derive debug_id from file content, not a filename Map Jul 31, 2026
@jhssilva jhssilva changed the title [dop] [error-tracking]: derive debug_id from file content, not a filename Map [dop] [error-tracking]: derive debug_id from file content Jul 31, 2026
@jhssilva jhssilva self-assigned this Jul 31, 2026
Comment thread packages/plugins/injection/src/xpack.ts Outdated
Comment on lines +137 to +142
const fileName = path.basename(file);
// `file` is already relative to the output directory (and may
// include subdirectories for nested chunks), matching the
// relativePath computed for sourcemap uploads in
// error-tracking/src/sourcemaps/files.ts. Do not collapse it to
// a basename or debug-id lookups by relative path will never match.
const fileName = file.split(path.sep).join('/');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

the same concern

Comment thread packages/plugins/injection/src/esbuild.ts Outdated
Comment thread packages/core/src/helpers/fs.ts Outdated
…e Map

The RUM plugin injects a debug_id into every built chunk's own JS
content. error-tracking's sourcemap uploader now extracts that
debug_id back out of each file when it uploads that file's sourcemap,
instead of relying on filename-based coordination between the two
plugins.

Previously, error-tracking got the debug_id from a side-channel Map
that the RUM plugin populated at injection time, keyed by the chunk's
filename. Bundlers (webpack/rspack) rename chunks after injection via
realContentHash, so by the time error-tracking looked the value up by
the chunk's final filename, the key no longer matched — the debug_id
was silently dropped for almost every chunk in a real build.

Instead of coordinating through a filename-keyed Map, error-tracking
now reads each minified file's own content directly and extracts the
debug_id from the ddDebugId literal the RUM plugin already embeds
inside it. This works no matter what renaming the bundler does
afterward, since the debug_id travels with the file's content, not
its name.
@jhssilva
jhssilva force-pushed the hugo.silva/fix-debug-id-key-path branch from 9a8a985 to 9e20c37 Compare July 31, 2026 15:30
…op unrelated fileName plumbing

extractDebugId now takes a file path and owns the read+regex composition
directly, instead of sender.ts composing readFilePrefix + extractDebugId
itself. Removes the now-unneeded readFilePrefix import from sender.ts.

Also reverts the esbuild.ts/xpack.ts fileName changes back to bare
basenames — that relative-path plumbing was left over from the old
filename-keyed debug_id lookup this PR removes, and nothing in this
diff depends on it anymore.
Per review, readFilePrefix had a single call site (debugId.ts) so it
didn't warrant living in the shared fs helpers. The byte-limited read
is now implemented directly inside debugId.ts.

Since debugId.ts's file read is no longer mockable through the shared
addFixtureFiles fixture system, its tests (and the one sender.ts test
that exercises real debug_id extraction) now write real temp files
instead, matching the pattern already used by fs.test.ts's own
(now-removed) readFilePrefix tests.
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.

4 participants