{"record":{"id":"d9a51ca4fdac15e6","repo":"mochajs/mocha","slug":"unsupported-url-protocol-parsed-protocol-onl","errorCode":null,"errorMessage":"Unsupported URL protocol \"${parsed.protocol}\". Only \"file:\" URLs are supported.","messagePattern":"Unsupported URL protocol \"(.+?)\"\\. Only \"file:\" URLs are supported\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/nodejs/esm-utils.cjs","lineNumber":159,"sourceCode":"}\n\nfunction dealWithExports(module) {\n  if (module.default) {\n    return module.default;\n  } else {\n    return { ...module, default: undefined };\n  }\n}\n\nconst resolveFile = (file) => {\n  if (URL.canParse(file)) {\n    const parsed = new URL(file);\n    // Single-letter \"protocols\" (e.g. \"d:\") are Windows drive letters, not URL schemes\n    if (parsed.protocol.length > 2) {\n      if (parsed.protocol === \"file:\") {\n        return url.fileURLToPath(parsed);\n      }\n      throw new Error(\n        `Unsupported URL protocol \"${parsed.protocol}\". Only \"file:\" URLs are supported.`,\n      );\n    }\n  }\n  return path.resolve(file);\n};\n\nexports.loadFilesAsync = async (\n  files,\n  preLoadFunc,\n  postLoadFunc,\n  esmDecorator,\n) => {\n  for (const file of files) {\n    preLoadFunc(file);\n    const result = await exports.requireOrImport(\n      resolveFile(file),\n      esmDecorator,","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/mochajs/mocha/blob/6bcbee4fd9a95351cedf0fdcb14c7d696486bc5a/lib/nodejs/esm-utils.cjs#L141-L177","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (.mocharc.json)\n{ \"spec\": [\"https://example.com/tests/main.spec.mjs\"] }\n\n// after\n{ \"spec\": [\"./tests/main.spec.mjs\"] }","handlingStrategy":"validation","validationCode":"function assertLoadableSpec(file) {\n  try {\n    const u = new URL(file);\n    if (u.protocol.length > 2 && u.protocol !== 'file:') {\n      throw new Error(`Spec must be a path or file: URL, got ${u.protocol}`);\n    }\n  } catch (e) {\n    if (!(e instanceof TypeError)) throw e; // TypeError = not a URL, plain path is fine\n  }\n}","typeGuard":"const isFileUrlOrPath = (f) => {\n  try { return new URL(f).protocol === 'file:'; } catch { return true; }\n};","tryCatchPattern":"try {\n  await importEsm(resolveFile(spec));\n} catch (err) {\n  if (err.message.startsWith('Unsupported URL protocol')) {\n    console.error('Convert remote URLs to local file paths before running specs.');\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["esm","url","file-loading"],"backgroundTag":"unsupported-url-protocol","analyzedSha":"6bcbee4fd9a95351cedf0fdcb14c7d696486bc5a","analyzedAt":"2026-09-01T03:41:47.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}