ERR_UNSUPPORTED_ESM_URL_SCHEME node module_error ai_generated true

Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader.

ID: node/err-unsupported-esm-url-scheme

Also available as: JSON · Markdown
91%Fix Rate
90%Confidence
40Evidence
2021-01-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
20 active

Root Cause

Windows file paths (C:\...) are being treated as URLs by the ESM loader. The drive letter 'C:' is interpreted as a URL scheme. Convert file paths to file:// URLs using url.pathToFileURL().

generic

Workarounds

  1. 95% success Use url.pathToFileURL() to convert file paths to file:// URLs
    import { pathToFileURL } from 'url'; const mod = await import(pathToFileURL(filePath).href); This converts 'C:\foo\bar.js' to 'file:///C:/foo/bar.js' which is a valid ESM URL.

    Sources: https://nodejs.org/api/url.html#urlpathtofileurlpath

  2. 88% success Use import.meta.dirname (Node 21.2+) instead of URL manipulation
    import.meta.dirname gives a plain path string directly, avoiding URL scheme issues. import.meta.filename provides the full file path. These are available since Node 21.2 and stable in Node 22+.

    Sources: https://nodejs.org/api/esm.html#importmetadirname

  3. 92% success Use fileURLToPath for path operations and pathToFileURL for imports
    Establish a consistent two-way conversion pattern: const __dirname = fileURLToPath(new URL('.', import.meta.url)); for path operations, and pathToFileURL() when passing back to import(). This handles both Unix and Windows correctly.

Dead Ends

Common approaches that don't work:

  1. Changing the type field in package.json between module and commonjs 85% fail

    This error is not about ESM vs CJS mode. It is about Windows file paths being treated as URLs in ESM dynamic imports. Switching module type does not fix path resolution.

  2. Using path.resolve() instead of import.meta.url 80% fail

    path.resolve() returns a file system path string. ESM dynamic import() expects a URL. Passing a Windows path (C:\foo\bar) to import() triggers this error because 'C:' is parsed as a URL scheme.

Error Chain

Frequently confused with: