{"record":{"id":"dc4ef3f7be9bad9d","repo":"remix-run/remix","slug":"mounts-values-must-be-relative-to-rootdir-receive","errorCode":null,"errorMessage":"mounts values must be relative to rootDir. Received \"${fileRoot}\".","messagePattern":"mounts values must be relative to rootDir\\. Received \"(.+?)\"\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/assets/src/lib/routes.ts","lineNumber":112,"sourceCode":"        urlPathname: joinUrlPath(mount.urlRoot, encodedFilePath),\n        urlRoot: mount.urlRoot,\n      }\n    }\n\n    return null\n  }\n}\n\nfunction compileMount(\n  urlRoot: string,\n  fileRoot: string,\n  options: {\n    basePath: string\n    rootDir: string\n  },\n): CompiledMount {\n  if (isAbsoluteFilePath(fileRoot)) {\n    throw new TypeError(`mounts values must be relative to rootDir. Received \"${fileRoot}\".`)\n  }\n\n  return {\n    fileRoot: resolveMountFileRoot(options.rootDir, fileRoot),\n    fileRootValue: fileRoot,\n    urlRoot: joinUrlPath(normalizeMountUrlRoot(options.basePath), normalizeMountUrlRoot(urlRoot)),\n    urlRootKey: urlRoot,\n  }\n}\n\nfunction normalizeMountUrlRoot(urlRoot: string): string {\n  let normalizedRoot = normalizePathname(urlRoot).replace(/\\/+$/, '') || '/'\n  let url = new URL(normalizedRoot, 'http://remix.run')\n\n  if (\n    url.search !== '' ||\n    url.hash !== '' ||\n    getUrlPathSegmentCount(url.pathname) !== getUrlPathSegmentCount(normalizedRoot)","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/assets/src/lib/routes.ts#L94-L130","documentation":"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.","triggerScenarios":"Passing `mounts: { '/assets': '/home/me/app/public' }` (absolute path) or a Windows absolute path like 'C:\\\\app\\\\public' to configMounts/compileMount.","commonSituations":"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).","solutions":["Use a relative path from rootDir: mounts: { '/assets': 'public/assets' }","Strip the rootDir prefix when generating: path.relative(rootDir, absPath)","On Windows, also avoid drive-letter absolute paths"],"exampleFix":"// before\nmounts: { '/assets': '/home/me/app/public/assets' }\n// after\nmounts: { '/assets': 'public/assets' }","handlingStrategy":"validation","validationCode":"import { isAbsolute } from 'node:path'\nfor (const [k, v] of Object.entries(mounts)) {\n  if (isAbsolute(v)) mounts[k] = relative(rootDir, v)\n}","typeGuard":"function isRelativeMount(v: string): boolean {\n  return !v.startsWith('/') && !/^[A-Za-z]:[\\\\/]/.test(v)\n}","tryCatchPattern":null,"preventionTips":["Never build mounts with path.resolve; use relative() from rootDir","Add a config lint step asserting mounts values are relative"],"tags":["config","routes","mounts","paths","assets"],"backgroundTag":"invalid-path","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}