Skip to content

[RUM-16940] add --debug-id upload mode for web sourcemaps#2374

Merged
amortemousque merged 7 commits into
masterfrom
aymeric/debug-id-for-web
Jul 16, 2026
Merged

[RUM-16940] add --debug-id upload mode for web sourcemaps#2374
amortemousque merged 7 commits into
masterfrom
aymeric/debug-id-for-web

Conversation

@amortemousque

@amortemousque amortemousque commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Context

When an error spans multiple micro-frontends, unminification breaks because all frames are resolved using the top frame’s (service, version).

This PR adds support for debug_id sourcemaps by extracting the debug_id (a TC39 proposal) from the source file and including it in the upload metadata. This enables the backend to resolve sourcemaps per frame using debug_id instead of a shared (service, version).

What this PR does

Adds a --debug-id flag to sourcemaps upload. When set:

  • --service, --release-version, and --minified-path-prefix are forbidden when --debug-id is present
  • The CLI reads the debug_id from the bundle's ddDebugId runtime snippet (injected by the build plugin)
  • The upload event metadata includes debug_id instead of service/version/minified_url

Test plan

  • yarn build
  • yarn test packages/base/src/commands/sourcemaps
  • Manual: yarn launch sourcemaps upload <path> --debug-id --dry-run
  • Manual: yarn launch sourcemaps upload <path> — validates and rejects missing flags

@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jun 22, 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: d0191ae | Docs | Datadog PR Page | Give us feedback!

@amortemousque amortemousque changed the title feat(sourcemaps): add --debug-id flag for web sourcemap uploads [RUM-16940] add --debug-id flag for web sourcemap uploads Jun 22, 2026
@amortemousque amortemousque changed the title [RUM-16940] add --debug-id flag for web sourcemap uploads feat(sourcemaps): add --debug-id upload mode for web sourcemaps Jun 22, 2026
@amortemousque amortemousque changed the title feat(sourcemaps): add --debug-id upload mode for web sourcemaps [RUM-16940] add --debug-id upload mode for web sourcemaps Jun 22, 2026
@amortemousque amortemousque added the rum Related to [dsyms, flutter-symbols, react-native, sourcemaps, unity-symbols] label Jun 22, 2026
@amortemousque amortemousque force-pushed the aymeric/debug-id-for-web branch from 74628e3 to 616359c Compare June 23, 2026 14:37
amortemousque and others added 2 commits July 2, 2026 11:14
Adds support for identifying sourcemaps via debug IDs (extracted from
the bundle's _ddDebugIds snippet) as an alternative to service/version/
minified-path-prefix. Refactors asMultipartPayload and getMetadataPayload
to accept a SourcemapUploadOptions object, and adds test fixtures and
unit tests for debug ID extraction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…load output

- Move extractDebugId into debugId.ts with a module-level DD_DEBUG_ID_REGEX
- Support single-quoted keys and values in the regex
- Print extracted debug ID in dry-run and live upload output via renderUpload
- Add debugId.test.ts covering multiple snippet formats and error cases
- Add execute-level dry-run test checking debug ID appears in output

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@amortemousque amortemousque force-pushed the aymeric/debug-id-for-web branch from 616359c to 8f7bda1 Compare July 2, 2026 09:15
@amortemousque amortemousque marked this pull request as ready for review July 3, 2026 08:48
@amortemousque amortemousque requested review from a team as code owners July 3, 2026 08:48
@Drarig29 Drarig29 changed the title [RUM-16940] add --debug-id upload mode for web sourcemaps [RUM-16940] add --debug-id upload mode for web sourcemaps Jul 3, 2026

@datadog-datadog-prod-us1-2 datadog-datadog-prod-us1-2 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.

Datadog Autotest: FAIL

When --debug-id mode is enabled but the debug ID cannot be extracted from the bundle, the code continues with an upload containing no sourcemap identifier. JSON.stringify silently omits undefined fields, resulting in metadata that the backend cannot match to error frames, causing silent sourcemap failures. The PR lacks validation to fail fast when extraction fails.

View proposed fix
📊 Validated against 7 scenarios · Open Bits AI session

🤖 Datadog Autotest · Commit 8f7bda1 · What is Autotest? · Any feedback? Reach out in #autotest

this.releaseVersion!,
this.projectPath ?? ''
)
const debugId = this.debugId ? extractDebugId(sourcemap.minifiedFilePath, this.context) : undefined

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P0 Missing validation allows sourcemap uploads with no identifier when debug ID extraction fails

Sourcemap uploads fail silently. Error frames cannot be unminified. Production RUM events show unminified error stacks instead of source code.

Assertion details
  • Input: User runs: datadog-ci sourcemaps upload ./dist --debug-id where bundle has no ddDebugId snippet
  • Expected: Command should fail with error message, or require fallback to traditional mode with service/version/prefix
  • Actual: extractDebugId returns undefined, code continues with asMultipartPayload called with service=undefined, version=undefined, debugId=undefined. JSON.stringify silently omits these fields. Backend receives only {cli_version, type, minified_url} with no sourcemap identifier.

Was this helpful? React 👍 or 👎
🤖 Datadog Autotest · What is Autotest? · Any feedback? Reach out in #autotest

@amortemousque amortemousque Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already handled — in --debug-id mode a payload is never uploaded without an identifier:

  1. Per file: a sourcemap with no ddDebugId is skipped (missing_debug_id) in validation, before asMultipartPayload is built.
  2. All files: if none yield a debug ID, the command aborts with exit 1 (No debug ID found in any minified file. Aborting upload.) before any upload.

- addDebugIdToPayloads sets each payload's debugId and gates the abort
- fold missing-debug-ID skip into validatePayload as an InvalidPayload
- move debug-ID messages into renderer; keep extractDebugId pure
- add debugId.test.ts coverage and partial-debug-id fixture

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@buranmert buranmert left a comment

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.

LGTM but i left 2 comments before approving


import type {Sourcemap} from './interfaces'

const DD_DEBUG_ID_REGEX = /["']ddDebugId["']\s*:\s*["']([^"']+)["']/

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.

can we use a more strict regex for UUID format like this? or do some bundlers use non-UUID debugIDs and we need to accept them too?

@amortemousque amortemousque Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I used the same pattern as the format

Comment thread packages/base/src/commands/sourcemaps/debugId.ts
})
}

private validateOptions(): boolean {

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.

(i chose a random line to leave this comment)

should we allow the customers to specify service,version,path and debug_id at the same time? or should we enforce one of these ways?

for example i'm a customer
yesterday i did datadog-ci sourcemaps upload --service foo1 --version bar111 --debug_id 123-456
if today i do datadog-ci sourcemaps upload --service foo2 --version bar222 --debug_id 123-456 this will be dropped in our ingestion pipeline as debug_id is a duplicate ❌

i'm wondering if this can create confusion
• IMO either we can disallow usage of service,version,path and debug_id at the same time
• or we can simply log a warning in terminal saying "service,version,path will be ignored as debug_id is already provided"

what do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You’re right. I’ll update it to forbid using service and version alongside --debug-id.

@amortemousque amortemousque Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done d5d3088

Copilot AI 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.

Pull request overview

Adds a new --debug-id mode to the sourcemaps upload command to support per-frame sourcemap resolution (for multi–micro-frontend stacks) by extracting a ddDebugId from minified bundles and sending it as upload metadata.

Changes:

  • Adds --debug-id flag, option validation logic, and debug-id extraction from minified JS bundles.
  • Updates sourcemap payload metadata generation and CLI output to incorporate debug_id.
  • Adds Jest coverage plus new fixtures for debug-id and partial-debug-id scenarios.

Reviewed changes

Copilot reviewed 7 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/base/src/commands/sourcemaps/validation.ts Adds validation to require a debug ID per payload when debug-id mode is enabled.
packages/base/src/commands/sourcemaps/upload.ts Adds --debug-id flag, new option validation, debug-id extraction gate, and updates payload building call-site.
packages/base/src/commands/sourcemaps/renderer.ts Updates command/info output and upload rendering to include debug-id context and new abort message.
packages/base/src/commands/sourcemaps/interfaces.ts Adds debugId to Sourcemap and refactors multipart payload creation to accept an options object including debug_id.
packages/base/src/commands/sourcemaps/debugId.ts New helper for extracting ddDebugId from bundle content and populating payloads.
packages/base/src/commands/sourcemaps/tests/upload.test.ts Adds unit tests for validateOptions and integration-style tests for debug-id upload behavior.
packages/base/src/commands/sourcemaps/tests/fixtures/bundle-with-partial-debug-id/a.min.js.map New fixture sourcemap for a bundle that includes a debug ID.
packages/base/src/commands/sourcemaps/tests/fixtures/bundle-with-partial-debug-id/a.min.js New fixture minified JS containing the ddDebugId snippet.
packages/base/src/commands/sourcemaps/tests/fixtures/bundle-with-partial-debug-id/b.min.js.map New fixture sourcemap for a bundle without a debug ID.
packages/base/src/commands/sourcemaps/tests/fixtures/bundle-with-partial-debug-id/b.min.js New fixture minified JS without the debug ID snippet.
packages/base/src/commands/sourcemaps/tests/fixtures/bundle-with-debug-id/common.min.js.map New fixture sourcemap for a bundle that includes a debug ID.
packages/base/src/commands/sourcemaps/tests/fixtures/bundle-with-debug-id/common.min.js New fixture minified JS containing the ddDebugId snippet.
packages/base/src/commands/sourcemaps/tests/debugId.test.ts New unit tests for debug-id extraction and payload mutation logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/base/src/commands/sourcemaps/interfaces.ts
Comment thread packages/base/src/commands/sourcemaps/upload.ts
Comment thread packages/base/src/commands/sourcemaps/upload.ts Outdated
…ied-path-prefix instead

Copilot review flagged --project-path as wrongly rejected in debug-id mode; it's still used and sent in the event payload. --minified-path-prefix is the option that actually conflicts, per the PR description.
…e found

addDebugIdToPayloads([]) returns false, so --debug-id mode wrongly exited 1 with a misleading "No debug ID found" error when zero sourcemaps matched, unlike non-debug-id mode which exits 0 in that case.
@amortemousque amortemousque merged commit 7660ba5 into master Jul 16, 2026
34 checks passed
@amortemousque amortemousque deleted the aymeric/debug-id-for-web branch July 16, 2026 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rum Related to [dsyms, flutter-symbols, react-native, sourcemaps, unity-symbols]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants