Skip to content

fix(ext/node): don't panic when main module path has invalid percent-encoding#35534

Merged
bartlomieju merged 3 commits into
denoland:mainfrom
minato32:fix/34178-bootstrap-uri-panic
Jul 2, 2026
Merged

fix(ext/node): don't panic when main module path has invalid percent-encoding#35534
bartlomieju merged 3 commits into
denoland:mainfrom
minato32:fix/34178-bootstrap-uri-panic

Conversation

@minato32

Copy link
Copy Markdown
Contributor

Closes #34178.

When the node process polyfill bootstraps, it sets process.argv[1] from Deno.mainModule by converting the file: URL to a path. That conversion ends in decodeURIComponent, which throws URIError: URI malformed if the path contains invalid percent-encoding (e.g. a non-UTF-8 byte). Since this happens during bootstrap, the uncaught throw aborts the runtime with a panic:

thread 'main' panicked at runtime/worker.rs:745:
Bootstrap exception: URIError: URI malformed
    at decodeURIComponent (<anonymous>)
    at pathFromURLPosix (ext:deno_web/00_infra.js)

This was hit in the wild via yt-dlp's deno provider (#34178).

The decode itself is not wrong — Node throws the same URIError from fileURLToPath for these paths — so this only fixes the crash: the conversion is guarded and falls back to the raw specifier when it can't be decoded, so a non-decodable main module no longer takes down the process.

Reproducing the exact filesystem state is awkward on macOS (the path needs a non-UTF-8 byte), so the regression test exercises the extracted helper directly with a malformed URL.

minato32 and others added 2 commits June 26, 2026 14:28
…encoding

`process.argv[1]` is derived from `Deno.mainModule` during the node process
bootstrap by converting the `file:` URL to a path. That conversion calls
`decodeURIComponent`, which throws `URIError: URI malformed` when the path
contains invalid percent-encoding (e.g. a non-UTF-8 byte). Because this runs
in bootstrap, the uncaught throw aborts the runtime with a panic
("Bootstrap exception: URIError: URI malformed").

Guard the conversion and fall back to the raw specifier so a non-decodable
main module can't crash the process. The decode still matches Node, which
also throws from `fileURLToPath` for such paths; only the panic is fixed.

Closes denoland#34178
Keep the bootstrap panic guard (fall back to the raw specifier when the
main module path can't be decoded), but stop exposing the helper on the
internals bag purely for testing. The synthetic unit test drove the
helper with a hand-made string and did not exercise the real bootstrap
path, so remove it rather than leave a test-only entry on internals.

@bartlomieju bartlomieju left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks

The mainModuleArgv refactor consolidated two Deno.mainModule reads into
one, dropping the count from 32 to 31.
@bartlomieju
bartlomieju merged commit 2c4414a into denoland:main Jul 2, 2026
136 checks passed
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.

Panic while using in yt-dlp

2 participants