remix-run/remix · error · TypeError

mounts values must be relative to rootDir. Received "${fileR

Error message

mounts values must be relative to rootDir. Received "${fileRoot}".

What it means

In route `mounts` configuration, each value (the file root) must be a path relative to rootDir. compileMount rejects absolute file paths because the library resolves mounts against rootDir itself, and absolute values would break portability and overlap detection.

Source

Thrown at packages/assets/src/lib/routes.ts:112

        urlPathname: joinUrlPath(mount.urlRoot, encodedFilePath),
        urlRoot: mount.urlRoot,
      }
    }

    return null
  }
}

function compileMount(
  urlRoot: string,
  fileRoot: string,
  options: {
    basePath: string
    rootDir: string
  },
): CompiledMount {
  if (isAbsoluteFilePath(fileRoot)) {
    throw new TypeError(`mounts values must be relative to rootDir. Received "${fileRoot}".`)
  }

  return {
    fileRoot: resolveMountFileRoot(options.rootDir, fileRoot),
    fileRootValue: fileRoot,
    urlRoot: joinUrlPath(normalizeMountUrlRoot(options.basePath), normalizeMountUrlRoot(urlRoot)),
    urlRootKey: urlRoot,
  }
}

function normalizeMountUrlRoot(urlRoot: string): string {
  let normalizedRoot = normalizePathname(urlRoot).replace(/\/+$/, '') || '/'
  let url = new URL(normalizedRoot, 'http://remix.run')

  if (
    url.search !== '' ||
    url.hash !== '' ||
    getUrlPathSegmentCount(url.pathname) !== getUrlPathSegmentCount(normalizedRoot)

View on GitHub (pinned to 9696913134)

Solutions

  1. Use a relative path from rootDir: mounts: { '/assets': 'public/assets' }
  2. Strip the rootDir prefix when generating: path.relative(rootDir, absPath)
  3. On Windows, also avoid drive-letter absolute paths

Example fix

// before
mounts: { '/assets': '/home/me/app/public/assets' }
// after
mounts: { '/assets': 'public/assets' }
Defensive patterns

Strategy: validation

Validate before calling

import { isAbsolute } from 'node:path'
for (const [k, v] of Object.entries(mounts)) {
  if (isAbsolute(v)) mounts[k] = relative(rootDir, v)
}

Type guard

function isRelativeMount(v: string): boolean {
  return !v.startsWith('/') && !/^[A-Za-z]:[\\/]/.test(v)
}

Prevention

When it happens

Trigger: Passing `mounts: { '/assets': '/home/me/app/public' }` (absolute path) or a Windows absolute path like 'C:\\app\\public' to configMounts/compileMount.

Common situations: Generating mounts config from __dirname/path.resolve, or porting config from another tool that accepts absolute paths; monorepo configs built with path.join(root, dir).

Related errors


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