{"record":{"id":"a8d8d4062f2b7c42","repo":"expo/expo","slug":"fileurltopath-not-a-file-url-href","errorCode":null,"errorMessage":"fileURLToPath: not a file URL: ${href}","messagePattern":"fileURLToPath: not a file URL: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/expo-go/tools/device-transformer/shims/url.js","lineNumber":24,"sourceCode":"        constructor(href) {\n          this.href = String(href);\n          const m = this.href.match(/^([a-z]+:)\\/\\/([^/]*)(.*)$/i);\n          this.protocol = m ? m[1] : '';\n          this.host = m ? m[2] : '';\n          this.pathname = m ? m[3] : this.href;\n          this.search = '';\n          this.hash = '';\n        }\n        toString() {\n          return this.href;\n        }\n      };\nfunction pathToFileURL(p) {\n  return new URLImpl('file://' + String(p).split('/').map(encodeURIComponent).join('/'));\n}\nfunction fileURLToPath(u) {\n  const href = typeof u === 'string' ? u : u.href;\n  if (!href.startsWith('file://')) throw new Error('fileURLToPath: not a file URL: ' + href);\n  return decodeURIComponent(href.slice(7));\n}\nmodule.exports = {\n  URL: URLImpl,\n  URLSearchParams: globalThis.URLSearchParams,\n  pathToFileURL,\n  fileURLToPath,\n  parse: (s) => new URLImpl(s),\n  format: (u) => String(u),\n};\n","sourceCodeStart":6,"sourceCodeEnd":35,"githubUrl":"https://github.com/expo/expo/blob/b09195aac27c9e4a63daaf12dcb6f00b6b2e08ee/apps/expo-go/tools/device-transformer/shims/url.js#L6-L35","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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://')) ...`."],"exampleFix":"// before\nconst p = fileURLToPath('/etc/hosts'); // missing scheme\n\n// after\nconst p = fileURLToPath(pathToFileURL('/etc/hosts'));","handlingStrategy":"validation","validationCode":"function safeFileURLToPath(u: string | URL): string | null {\n  const href = typeof u === 'string' ? u : u.href;\n  if (!href.startsWith('file://')) return null;\n  return fileURLToPath(u);\n}","typeGuard":"function isFileURL(u: string | URL): boolean {\n  const href = typeof u === 'string' ? u : u.href;\n  return href.startsWith('file://');\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["url","fileurl","hermes","shim","validation"],"backgroundTag":null,"analyzedSha":"b09195aac27c9e4a63daaf12dcb6f00b6b2e08ee","analyzedAt":"2026-08-12T15:59:58.304Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}