expo/expo · error · Error
fileURLToPath: not a file URL: ${href}
Error message
fileURLToPath: not a file URL: ${href} What it means
Thrown by `fileURLToPath` in the `url` shim when the input does not start with the `file://` scheme. `fileURLToPath` is the inverse of `pathToFileURL` and is only meaningful for `file:` URLs; passing an http URL, a bare path, or a non-file URL object is an error. The shim replicates Node's `url.fileURLToPath` contract for the Hermes runtime.
Source
Thrown at apps/expo-go/tools/device-transformer/shims/url.js:24
constructor(href) {
this.href = String(href);
const m = this.href.match(/^([a-z]+:)\/\/([^/]*)(.*)$/i);
this.protocol = m ? m[1] : '';
this.host = m ? m[2] : '';
this.pathname = m ? m[3] : this.href;
this.search = '';
this.hash = '';
}
toString() {
return this.href;
}
};
function pathToFileURL(p) {
return new URLImpl('file://' + String(p).split('/').map(encodeURIComponent).join('/'));
}
function fileURLToPath(u) {
const href = typeof u === 'string' ? u : u.href;
if (!href.startsWith('file://')) throw new Error('fileURLToPath: not a file URL: ' + href);
return decodeURIComponent(href.slice(7));
}
module.exports = {
URL: URLImpl,
URLSearchParams: globalThis.URLSearchParams,
pathToFileURL,
fileURLToPath,
parse: (s) => new URLImpl(s),
format: (u) => String(u),
};
View on GitHub (pinned to b09195aac2)
Solutions
- Convert the path to a file URL first: `fileURLToPath(pathToFileURL(p))` is a no-op-safe round trip.
- If you already have a plain path string, skip fileURLToPath and use it directly.
- Validate the scheme before calling: `if (String(url).startsWith('file://')) ...`.
Example fix
// before
const p = fileURLToPath('/etc/hosts'); // missing scheme
// after
const p = fileURLToPath(pathToFileURL('/etc/hosts')); Defensive patterns
Strategy: validation
Validate before calling
function safeFileURLToPath(u: string | URL): string | null {
const href = typeof u === 'string' ? u : u.href;
if (!href.startsWith('file://')) return null;
return fileURLToPath(u);
} Type guard
function isFileURL(u: string | URL): boolean {
const href = typeof u === 'string' ? u : u.href;
return href.startsWith('file://');
} Prevention
- Use pathToFileURL to construct file URLs before round-tripping through fileURLToPath.
- If you already hold a plain path string, do not convert through URL at all.
- Validate the URL scheme at trust boundaries.
When it happens
Trigger: Calling `fileURLToPath('http://example.com/x')`, `fileURLToPath('/abs/path')` (missing scheme), or `fileURLToPath(new URL('https://...'))`. Any input whose href does not begin with `file://` triggers it.
Common situations: Passing a plain filesystem path instead of a file URL (forgetting to call `pathToFileURL` first); receiving a URL from an API and forwarding it without scheme-checking; mixing up `URL` instances from different origins.
Related errors
- Path must be a string. Received ${JSON.stringify(path)}
- "ext" argument must be a string
- The "pathObject" argument must be of type Object. Received t
- lightningcss.${name} is not available in the Hermes runtime
- tty.ReadStream not available in Hermes runtime
AI-assisted analysis of expo/expo@b09195aac2 (2026-08-12).
Data as JSON: /api/errors/a8d8d4062f2b7c42.
Report an issue: GitHub.