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

  1. Convert the path to a file URL first: `fileURLToPath(pathToFileURL(p))` is a no-op-safe round trip.
  2. If you already have a plain path string, skip fileURLToPath and use it directly.
  3. 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

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


AI-assisted analysis of expo/expo@b09195aac2 (2026-08-12). Data as JSON: /api/errors/a8d8d4062f2b7c42. Report an issue: GitHub.