remix-run/remix · error · TypeError

Expected a file path or file:// URL, received "${filePath}"

Error message

Expected a file path or file:// URL, received "${filePath}"

What it means

The script compiler resolves each input as either a plain file path (resolved against rootDir) or a file:// URL. Any other URL scheme (http://, https://, data:, custom://) throws because the compiler only reads local files.

Source

Thrown at packages/assets/src/lib/scripts/compiler.ts:297

      if (resolvedOptions.fingerprintAssets && parsedPathname.requestedFingerprint === null)
        return null

      return {
        cacheControl: getFingerprintRequestCacheControl(parsedPathname.requestedFingerprint),
        filePath,
        isSourceMapRequest: parsedPathname.isSourceMapRequest,
        requestedFingerprint: parsedPathname.requestedFingerprint,
      }
    },
  }

  function resolveInputFilePath(filePath: string): string {
    if (filePath.startsWith('file://')) {
      return normalizeFilePath(fileURLToPath(new URL(filePath)))
    }

    if (filePath.includes('://')) {
      throw new TypeError(`Expected a file path or file:// URL, received "${filePath}"`)
    }

    return resolveFilePath(resolvedOptions.rootDir, filePath)
  }

  function invalidateScriptFileEvent(normalizedFilePath: string, event: ModuleWatchEvent): void {
    if (isWatchIgnored(normalizedFilePath)) return

    if (shouldClearResolverCacheForFileEvent(normalizedFilePath, event)) {
      resolverFactory.clearCache()
    }

    if (isTsconfigPath(normalizedFilePath)) {
      tsconfigTransformOptionsResolver.clear()
      scriptStore.invalidateAll()
      return
    }

View on GitHub (pinned to 9696913134)

Solutions

  1. Download/ vendor the remote script locally and reference the file path
  2. Use a file:// URL for unusual local paths: 'file:///abs/path/app.ts'
  3. Filter remote URLs out before passing paths to the compiler

Example fix

// before
resolveInputFilePath('https://cdn.example.com/app.ts')
// after
resolveInputFilePath('app.ts') // relative to rootDir
Defensive patterns

Strategy: validation

Validate before calling

function isLocal(p: string) { return !p.includes('://') || p.startsWith('file://') }
if (!scripts.every(isLocal)) throw new Error('remote script paths not supported')

Type guard

function isLocalFilePath(p: string): boolean {
  return p.startsWith('file://') || !p.includes('://')
}

Prevention

When it happens

Trigger: Passing 'https://cdn.example.com/app.ts' or 'http://localhost/app.ts' as a script path to the scripts compiler (resolvedModule/getPreloadLayers).

Common situations: Feeding dependency URLs from import maps or CDN config into the compiler; mixing remote asset URLs with local entry points; config values sourced from a manifest containing absolute URLs.

Related errors


AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27). Data as JSON: /api/errors/a7f0c9b26c64e1b7. Report an issue: GitHub.