Skip to content

feat(sourcemaps): add local debug ID finder - #2471

Open
jhssilva wants to merge 4 commits into
masterfrom
hugo.silva/sourcemaps-find-debug-id
Open

feat(sourcemaps): add local debug ID finder#2471
jhssilva wants to merge 4 commits into
masterfrom
hugo.silva/sourcemaps-find-debug-id

Conversation

@jhssilva

@jhssilva jhssilva commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

What and why?

Adds a read-only datadog-ci sourcemaps find command for RUM-18157.

The command helps troubleshoot sourcemaps missing from Error Tracking by finding local minified JavaScript bundles and their corresponding sourcemaps, then showing the debug ID found in each artifact.

It supports two queries:

datadog-ci sourcemaps find ./dist --debug-id <uuid>
datadog-ci sourcemaps find ./dist --missing-debug-id

The output classifies each pair as matched, bundle-only, sourcemap-only, mismatched, missing, or error. --json provides machine-readable output.

This command only inspects local artifacts. It does not claim whether Datadog received or processed a sourcemap; remote lookup can be added separately in the future.

How?

  • Reuses the existing sourcemap discovery logic, including local sourceMappingURL references and legacy filename pairing.
  • Reads injected ddDebugId values from minified bundles asynchronously.
  • Parses sourcemaps incrementally in 64 KiB chunks with bounded memory, capturing only the top-level debug_id and ignoring nested values such as text in sourcesContent.
  • Applies the same UUID-shape validation to query, bundle, and sourcemap debug IDs.
  • Reports malformed IDs and absent or unreadable bundles as errors instead of classifying them as missing instrumentation.
  • Uses bounded concurrency and closes file handles before returning for cross-platform safety.

Validation

  • yarn test packages/base/src/commands/sourcemaps packages/datadog-ci/src/__tests__/cli.test.ts --runInBand --watchman=false — 7 suites, 258 tests
  • yarn build
  • yarn lint
  • yarn lint:packages
  • yarn lint:readme-usage
  • Compiled sourcemaps find validation against local artifact fixtures

Review checklist

  • Feature or bugfix has appropriate unit and command-level tests

@jhssilva
jhssilva requested review from a team as code owners August 27, 2026 08:27
@datadog-official

datadog-official Bot commented Aug 27, 2026

Copy link
Copy Markdown

Tests

All CI checks and tests passed.

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 9b92dc4 | Docs | View more details | Give us feedback!

@jhssilva jhssilva added the rum Related to [dsyms, flutter-symbols, react-native, sourcemaps, unity-symbols] label Aug 27, 2026

@datadog-official datadog-official 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

Large sourcemap sets can use all available Node.js memory. The resolver can also report wrong results for absent, unreadable, or malformed bundles.

Open Bits AI session

🤖 Datadog Autotest · Commit ab03a5f · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest


const readSourcemapDebugId = async (sourcemapPath: string): Promise<SourcemapDebugIdResult> => {
try {
const parsed = JSON.parse(await fs.promises.readFile(sourcemapPath, 'utf8')) as unknown

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Full sourcemap reads can use all memory

The command can use all available Node.js memory and stop before it returns results for a large build.

Assertion details
  • Input: Run the resolver with default concurrency on many large sourcemaps that contain sourcesContent.
  • Expected: The resolver must read the debug ID with bounded memory or use a separate safe limit for full-map reads.
  • Actual: The resolver reads and parses each complete sourcemap. Default concurrency permits 20 complete maps in memory at the same time.

Was this helpful? React 👍 or 👎
🤖 Datadog Autotest · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

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.

Fixed in 7a569df6. Sourcemaps are now parsed incrementally in 64 KiB chunks with bounded memory. Large sourcesContent values are scanned without being retained, and tests cover large maps plus debug_id values split across chunk boundaries.

await fileHandle.close()
}
} catch {
return 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.

P2 Bundle read errors look like missing IDs

The output directs users to fix instrumentation when the bundle is absent or unreadable.

Assertion details
  • Input: Use --missing-debug-id when legacy discovery finds an orphan .js.map file or a bundle cannot be read.
  • Expected: The resolver must report the bundle read error and must not classify it as a missing debug ID.
  • Actual: extractDebugIdAsync catches every bundle read error and returns undefined. The resolver then treats the bundle as if it exists without a debug ID.

Was this helpful? React 👍 or 👎
🤖 Datadog Autotest · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

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.

Fixed in 7a569df6. Asynchronous bundle extraction now returns file-read errors explicitly. The find command reports the error, excludes that artifact from --missing-debug-id results, and exits with status 1. A regression test covers an orphan sourcemap whose bundle is absent.

}

const searchableContent = overlap + buffer.toString('utf8', 0, bytesRead)
const debugId = matchDebugId(searchableContent)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Malformed bundle IDs pass validation

The command hides the bundle from --missing-debug-id and cannot find it with a valid --debug-id query.

Assertion details
  • Input: A bundle contains a 36-character ddDebugId value with misplaced hyphens.
  • Expected: The resolver must validate extracted bundle IDs with the same UUID shape that it uses for query and sourcemap IDs.
  • Actual: The shared matcher accepts any 36 hex or hyphen characters. The resolver treats a malformed value as a valid bundle debug ID.

Was this helpful? React 👍 or 👎
🤖 Datadog Autotest · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

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.

Fixed in 7a569df6. Extracted bundle values are now validated with the shared strict UUID matcher. A malformed ddDebugId produces an explicit error, is excluded from --missing-debug-id results, and is covered by a command-level regression test.

@jhssilva jhssilva changed the title feat(sourcemaps): add local debug ID resolver feat(sourcemaps): add local debug ID finder Aug 27, 2026
@evazorro evazorro self-assigned this Aug 27, 2026
@evazorro evazorro removed their assignment Aug 27, 2026
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.

2 participants