mochajs/mocha · error · Error
Unsupported URL protocol "${parsed.protocol}". Only "file:"
Error message
Unsupported URL protocol "${parsed.protocol}". Only "file:" URLs are supported. What it means
When importing ESM files, Mocha's `resolveFile` accepts either a plain filesystem path or a URL string. If the input parses as a URL whose protocol is not `file:` (e.g. `http:`, `https:`, `data:`), it throws this error because Mocha can only load specs from the local filesystem.
Source
Thrown at lib/nodejs/esm-utils.cjs:159
}
function dealWithExports(module) {
if (module.default) {
return module.default;
} else {
return { ...module, default: undefined };
}
}
const resolveFile = (file) => {
if (URL.canParse(file)) {
const parsed = new URL(file);
// Single-letter "protocols" (e.g. "d:") are Windows drive letters, not URL schemes
if (parsed.protocol.length > 2) {
if (parsed.protocol === "file:") {
return url.fileURLToPath(parsed);
}
throw new Error(
`Unsupported URL protocol "${parsed.protocol}". Only "file:" URLs are supported.`,
);
}
}
return path.resolve(file);
};
exports.loadFilesAsync = async (
files,
preLoadFunc,
postLoadFunc,
esmDecorator,
) => {
for (const file of files) {
preLoadFunc(file);
const result = await exports.requireOrImport(
resolveFile(file),
esmDecorator,View on GitHub (pinned to 6bcbee4fd9)
Solutions
- Pass a filesystem path instead of a URL: `mocha ./test/spec.mjs`.
- Convert remote URLs to local files first (download or resolve to the on-disk path).
- For file URLs, the `file:` scheme is fine — ensure the scheme is exactly `file:` (e.g. `file:///abs/path/spec.mjs`).
- Audit .mocharc/spec glob configuration for accidentally included URLs.
Example fix
// before (.mocharc.json)
{ "spec": ["https://example.com/tests/main.spec.mjs"] }
// after
{ "spec": ["./tests/main.spec.mjs"] } Defensive patterns
Strategy: validation
Validate before calling
function assertLoadableSpec(file) {
try {
const u = new URL(file);
if (u.protocol.length > 2 && u.protocol !== 'file:') {
throw new Error(`Spec must be a path or file: URL, got ${u.protocol}`);
}
} catch (e) {
if (!(e instanceof TypeError)) throw e; // TypeError = not a URL, plain path is fine
}
} Type guard
const isFileUrlOrPath = (f) => {
try { return new URL(f).protocol === 'file:'; } catch { return true; }
}; Try / catch
try {
await importEsm(resolveFile(spec));
} catch (err) {
if (err.message.startsWith('Unsupported URL protocol')) {
console.error('Convert remote URLs to local file paths before running specs.');
}
throw err;
} Prevention
- Always give Mocha local filesystem paths (or file: URLs) for specs.
- Sanitize CI variables that feed the spec list — ensure they resolve to paths.
- Never pass dev-server or CDN URLs as test entry points.
- Validate .mocharc spec arrays at config-load time.
When it happens
Trigger: Passing `mocha 'https://example.com/test.mjs'` or another remote URL as a spec; passing a URL with an exotic scheme (`webpack:`, `data:`); on Windows, a path like `D:\foo` can be misread as a URL but single-letter drive protocols are correctly allowed.
Common situations: CI configs where the spec path variable contains a URL; accidentally pasting a CDN/bundle URL into .mocharc spec arrays; tooling that resolves test files to `http://localhost/...` dev-server URLs instead of paths.
AI-assisted analysis of mochajs/mocha@6bcbee4fd9 (2026-09-01).
Data as JSON: /api/errors/d9a51ca4fdac15e6.
Report an issue: GitHub.