{"record":{"id":"3fcd9fc974f115ef","repo":"remix-run/remix","slug":"expected-a-file-path-or-file-url-received-f-3fcd9f","errorCode":null,"errorMessage":"Expected a file path or file:// URL, received \"${filePath}\"","messagePattern":"Expected a file path or file:// URL, received \"(.+?)\"","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/assets/src/lib/styles/compiler.ts","lineNumber":217,"sourceCode":"        path,\n        timestamp,\n      }))\n    },\n\n    invalidateFileEvent(filePath, event) {\n      let normalizedFilePath = normalizeFilePath(filePath)\n      if (isWatchIgnored(normalizedFilePath)) return\n      styleStore.invalidateForFileEvent(normalizedFilePath, event)\n    },\n  }\n\n  function resolveInputFilePath(filePath: string): string {\n    if (filePath.startsWith('file://')) {\n      return normalizeFilePath(fileURLToPath(new URL(filePath)))\n    }\n\n    if (filePath.includes('://')) {\n      throw new TypeError(`Expected a file path or file:// URL, received \"${filePath}\"`)\n    }\n\n    return resolveFilePath(resolvedOptions.rootDir, filePath)\n  }\n\n  async function getOrCreateResolvedStyles(records: StyleRecord[]): Promise<ResolvedStyle[]> {\n    return mapWithConcurrency(records, preloadConcurrency, (record) =>\n      getOrCreateResolvedStyle(record),\n    )\n  }\n\n  async function getOrCreateResolvedStyle(record: StyleRecord): Promise<ResolvedStyle> {\n    if (record.resolved && styleStore.isResolvedFresh(record)) return record.resolved\n\n    let cacheKey = getRecordCacheKey(record)\n    let existing = resolveInFlightByCacheKey.get(cacheKey)\n    if (existing) return existing\n","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/assets/src/lib/styles/compiler.ts#L199-L235","documentation":"The style compiler accepts only local file paths (resolved against rootDir) or file:// URLs for style inputs. Other URL schemes such as http:// or https:// throw, since the compiler must read styles from disk.","triggerScenarios":"Passing 'https://example.com/theme.css' as a style path to the styles compiler (resolvedStyle/getPreloadLayers).","commonSituations":"Referencing CDN-hosted CSS in config meant for local files; copying URLs from link tags in HTML into compiler options; importing styles by URL in environments that support it (Vite-style) but not here.","solutions":["Download the stylesheet locally and pass a relative path like 'styles/theme.css'","Use file:/// URLs for absolute local paths","Vendor third-party CSS into the project instead of remote references"],"exampleFix":"// before\nstylePath: 'https://cdn.example.com/theme.css'\n// after\nstylePath: 'styles/theme.css'","handlingStrategy":"validation","validationCode":"function isLocal(p: string) { return !p.includes('://') || p.startsWith('file://') }\nif (!styles.every(isLocal)) throw new Error('remote style paths not supported')","typeGuard":"function isLocalFilePath(p: string): boolean {\n  return p.startsWith('file://') || !p.includes('://')\n}","tryCatchPattern":null,"preventionTips":["Reference local CSS files in compiler options, not CDN URLs","Use file:/// URLs for absolute local paths"],"tags":["styles","compiler","url","paths","assets"],"backgroundTag":"unsupported-url-scheme","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}