Skip to content

[sourcemaps] Fix upload failure when sourceMappingURL is an absolute URL#2093

Merged
buranmert merged 2 commits intomasterfrom
fix/sourcemaps-absolute-url-fallback
Feb 9, 2026
Merged

[sourcemaps] Fix upload failure when sourceMappingURL is an absolute URL#2093
buranmert merged 2 commits intomasterfrom
fix/sourcemaps-absolute-url-fallback

Conversation

@raczosala
Copy link
Contributor

@raczosala raczosala commented Feb 7, 2026

Summary

Fixes a regression introduced in #2035 where sourcemaps upload fails to upload any sourcemaps when JS files contain an absolute URL in //# sourceMappingURL.

Background

PR #2035 added sourceMappingURL support: instead of relying on the legacy convention (foo.min.jsfoo.min.js.map), the upload command now reads the //# sourceMappingURL=... comment from each JS file to locate its corresponding sourcemap. If this new method finds no results, it falls back to the legacy .js.map lookup.

The problem

When sourceMappingURL contains an absolute URL (common with webpack/rspack SourceMapDevToolPlugin when publicPath is set to a CDN), upath.join produces an invalid local path:

// Given:
//   minifiedFilePath = "public/static/chunk.min.js"
//   sourceMappingURL = https://cdn.example.com/sourcemaps/chunk.min.js.map

const sourcemapPath = upath.join("public/static", "https://cdn.example.com/sourcemaps/chunk.min.js.map")
// Result: "public/static/https:/cdn.example.com/sourcemaps/chunk.min.js.map"

This path obviously doesn't exist on disk, so validatePayload skips it. But because the sourceMappingURL regex did match, the modern method returns a non-empty result set (of invalid entries), which means the legacy fallback is never triggered — resulting in zero sourcemaps uploaded.

The fix

Skip sourceMappingURL values that are absolute URLs (containing ://) or absolute paths (starting with /), returning undefined so they don't count as results. This allows the legacy .js.map fallback to take over for these files.

const sourcemapUrl = decodeURIComponent(sourceMappingMatch[1].trim())

// Skip absolute URLs and absolute paths — they can't be resolved to local files
if (sourcemapUrl.includes('://') || upath.isAbsolute(sourcemapUrl)) {
  return undefined
}

Examples

sourceMappingURL value Before (broken) After (fixed)
chunk.min.js.map (relative) Resolved via upath.join — works Same — no change
../maps/chunk.min.js.map (relative) Resolved via upath.join — works Same — no change
https://cdn.example.com/sourcemaps/chunk.min.js.map (absolute URL) upath.join produces invalid path, blocks legacy fallback Skipped, falls back to legacy .js.map lookup
/sourcemaps/chunk.min.js.map (absolute path) upath.join produces invalid path, blocks legacy fallback Skipped, falls back to legacy .js.map lookup

Test plan

  • Added integration test with a fixture containing //# sourceMappingURL=https://cdn.example.com/sourcemaps/chunk.min.js.map
  • Verifies the upload succeeds by falling back to the legacy method
  • All existing sourcemaps upload and utils tests pass
  • Lint passes

When JS files contain a full URL in `//# sourceMappingURL=` (e.g., a CDN
URL set by webpack/rspack SourceMapDevToolPlugin), `upath.join` produces
an invalid local path, causing all sourcemaps to be skipped with no
fallback to the legacy `.js.map` glob method.

Skip sourceMappingURL values that are absolute URLs (contain `://`) or
absolute paths (start with `/`) so the legacy fallback is correctly
triggered.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@raczosala raczosala requested review from a team as code owners February 7, 2026 00:05
@raczosala raczosala added the rum Related to [dsyms, flutter-symbols, react-native, sourcemaps, unity-symbols] label Feb 7, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Drarig29 Drarig29 requested a review from buranmert February 9, 2026 14:14
@buranmert buranmert requested a review from Copilot February 9, 2026 14:20
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a regression where sourcemaps upload fails to upload any sourcemaps when //# sourceMappingURL is an absolute URL, by skipping unresolvable values so the legacy .js.map fallback can run.

Changes:

  • Skip sourceMappingURL entries that are absolute URLs or absolute paths during sourcemap resolution.
  • Add an integration test fixture case validating fallback behavior for absolute URL sourceMappingURL.

Reviewed changes

Copilot reviewed 2 out of 4 changed files in this pull request and generated 2 comments.

File Description
packages/datadog-ci/src/commands/sourcemaps/upload.ts Ignores absolute sourceMappingURL values to allow legacy .js.map fallback.
packages/datadog-ci/src/commands/sourcemaps/tests/upload.test.ts Adds an integration test ensuring absolute-URL sourceMappingURL triggers the legacy fallback.

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

Comment on lines +203 to +204
// Skip absolute URLs and absolute paths — they can't be resolved to local files
if (sourcemapUrl.includes('://') || upath.isAbsolute(sourcemapUrl)) {
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

sourcemapUrl.includes('://') won’t catch other non-local sourceMappingURL forms that are also common/valid and would still produce an invalid joined path (and still block the legacy fallback), e.g. protocol-relative URLs (//cdn.example.com/...) and data URIs (data:application/json;base64,...). Consider expanding this guard to detect any URL scheme (e.g. ^[a-zA-Z][a-zA-Z\\d+.-]*:) and protocol-relative // in addition to upath.isAbsolute(...), so these cases get skipped too.

Suggested change
// Skip absolute URLs and absolute paths — they can't be resolved to local files
if (sourcemapUrl.includes('://') || upath.isAbsolute(sourcemapUrl)) {
// Skip non-local URLs and absolute paths — they can't be resolved to local files
const hasUrlScheme = /^[a-zA-Z][a-zA-Z\d+.-]*:/.test(sourcemapUrl)
const isProtocolRelative = sourcemapUrl.startsWith('//')
if (hasUrlScheme || isProtocolRelative || upath.isAbsolute(sourcemapUrl)) {

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

https://tc39.es/ecma426 defines sourceMappingURL as a URL, which can either be relative or absolute. So there will be a :// protocol.

Comment on lines +204 to +206
if (sourcemapUrl.includes('://') || upath.isAbsolute(sourcemapUrl)) {
return undefined
}
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

This change adds a new branch for absolute paths via upath.isAbsolute(sourcemapUrl), but the added integration test only covers the absolute-URL case. Add a test fixture where //# sourceMappingURL=/sourcemaps/chunk.min.js.map (absolute path) is present and assert the command falls back to the legacy .js.map lookup, so both sides of this condition are covered.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@buranmert buranmert left a comment

Choose a reason for hiding this comment

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

copilot has minor concerns but LGTM

@buranmert buranmert merged commit 3f76fb0 into master Feb 9, 2026
26 checks passed
@buranmert buranmert deleted the fix/sourcemaps-absolute-url-fallback branch February 9, 2026 14:56
@piloulacdog piloulacdog mentioned this pull request Feb 10, 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.

4 participants