denoland/deno · error · ERR_INVALID_URL_SCHEME
ERR_INVALID_URL_SCHEME
ERR_INVALID_URL_SCHEME
Error message
The URL must be one of scheme file or data
What it means
The Worker constructor only accepts URL objects whose protocol is file: or data: — worker code must exist on local disk or be inline. Any other scheme (http:, https:, blob:, ...) throws ERR_INVALID_URL_SCHEME with the allowed list ['file', 'data'], matching Node.js, which never fetches worker scripts over the network.
Source
Thrown at ext/node/polyfills/worker_threads.ts:376
hasInvalid = true;
break;
}
}
}
if (hasInvalid) {
throw new ERR_WORKER_INVALID_EXEC_ARGV(
[nodeOptions],
"invalid NODE_OPTIONS env variable",
);
}
}
}
if (typeof specifier === "object") {
if (
!(specifier.protocol === "data:" || specifier.protocol === "file:")
) {
throw new ERR_INVALID_URL_SCHEME(["file", "data"]);
}
} else if (typeof specifier === "string" && !options?.eval) {
// Node.js requires string specifiers to be absolute paths or
// relative paths starting with './' or '../'. URLs passed as
// strings must be wrapped with `new URL`.
if (
StringPrototypeStartsWith(specifier, "file://") ||
StringPrototypeStartsWith(specifier, "data:") ||
StringPrototypeStartsWith(specifier, "http://") ||
StringPrototypeStartsWith(specifier, "https://")
) {
throw new ERR_WORKER_PATH(specifier);
}
const path = specifier;
if (
!StringPrototypeStartsWith(path, "/") &&
!StringPrototypeStartsWith(path, "./") &&
!StringPrototypeStartsWith(path, "../") &&View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Fetch the script in the parent, write it to a temp file, and pass a file URL built with pathToFileURL().
- Use a data: URL for small inline scripts: new Worker(new URL('data:text/javascript,' + encodeURIComponent(code))).
- For local scripts, resolve relative to the module: new Worker(new URL('./w.js', import.meta.url)).
- Never attempt http(s) worker specifiers; materialize the code locally first.
Example fix
// before
const w = new Worker(new URL('https://cdn.example.com/w.js'));
// after
import { pathToFileURL } from 'node:url';
const code = await (await fetch('https://cdn.example.com/w.js')).text();
const tmp = await Deno.makeTempFile({ suffix: '.js' });
await Deno.writeTextFile(tmp, code);
const w = new Worker(pathToFileURL(tmp)); Defensive patterns
Strategy: type-guard
Validate before calling
const spec = new URL(input);
if (spec.protocol !== 'file:' && spec.protocol !== 'data:') {
throw new Error('worker URL must be file: or data:, got ' + spec.protocol);
}
const w = new Worker(spec); Type guard
function isWorkerUrl(u: unknown): u is URL {
return u instanceof URL && (u.protocol === 'file:' || u.protocol === 'data:');
} Try / catch
try { const w = new Worker(url); } catch (e) { if (e?.code === 'ERR_INVALID_URL_SCHEME') { /* download/bundle the script locally and switch to a file: URL */ } else throw e; } Prevention
- Resolve worker specifiers from import.meta.url so they are always file: URLs.
- Keep worker sources in the repo or build output instead of remote URLs.
- Assert isWorkerUrl(spec) at worker-creation call sites.
When it happens
Trigger: new Worker(new URL('https://example.com/w.mjs')) or new Worker(new URL('blob:...')) — any URL object whose .protocol is not 'file:' or 'data:'.
Common situations: Porting browser code that uses URL.createObjectURL(blob) for inline workers; pointing at CDN-hosted worker scripts; config systems that hand out http(s) URLs where a local module path was expected.
Related errors
- ERR_INVALID_URL_SCHEME
- ERR_INVALID_URL
- ERR_HTTP2_UNSUPPORTED_PROTOCOL
- ERR_INVALID_URL
- ERR_INSPECTOR_NOT_WORKER
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/167f94fe573b2152.
Report an issue: GitHub.