remix-run/remix · error · TypeError
mounts keys must not overlap. Received "${mount.urlRootKey}"
Error message
mounts keys must not overlap. Received "${mount.urlRootKey}" and "${otherMount.urlRootKey}". What it means
Two or more mounts keys (URL roots) overlap after normalization — one URL root is a prefix of another (or they are equal). validateNoOverlappingUrlRoots rejects this during compileRoutes because request routing would be ambiguous.
Source
Thrown at packages/assets/src/lib/routes.ts:192
if (rootsOverlap(mount.fileRoot, otherMount.fileRoot)) {
throw new TypeError(
`mounts values must not overlap. Received "${mount.fileRootValue}" and "${otherMount.fileRootValue}", resolving to "${mount.fileRoot}" and "${otherMount.fileRoot}".`,
)
}
}
}
}
function validateNoOverlappingUrlRoots(mounts: readonly CompiledMount[]): void {
for (let index = 0; index < mounts.length; index++) {
let mount = mounts[index]
for (let otherIndex = index + 1; otherIndex < mounts.length; otherIndex++) {
let otherMount = mounts[otherIndex]
if (!rootsOverlap(mount.urlRoot, otherMount.urlRoot)) continue
throw new TypeError(
`mounts keys must not overlap. Received "${mount.urlRootKey}" and "${otherMount.urlRootKey}".`,
)
}
}
}
function rootsOverlap(root: string, otherRoot: string): boolean {
return (
root === otherRoot ||
root === '/' ||
otherRoot === '/' ||
root.startsWith(`${otherRoot}/`) ||
otherRoot.startsWith(`${root}/`)
)
}
function isUnresolvedPathError(error: unknown, filePath: string): boolean {
// Windows reports UNKNOWN rather than ENOENT when a UNC share cannot be reached.View on GitHub (pinned to 9696913134)
Solutions
- Remove the overlapping parent or child URL mount and serve nested paths from the parent's directory structure
- If you need a different directory for a sub-path, restructure so URL roots are siblings, not nested
- Check for trailing-slash duplicates when generating mounts programmatically
Example fix
// before
mounts: { '/assets': 'public/assets', '/assets/img': 'img' }
// after
mounts: { '/assets': 'public/assets', '/img': 'img' } Defensive patterns
Strategy: validation
Validate before calling
const roots = Object.keys(mounts).map((k) => k.replace(/\/+$/, '') || '/')
for (let i = 0; i < roots.length; i++)
for (let j = i + 1; j < roots.length; j++)
if (roots[i] === roots[j] || roots[j].startsWith(roots[i] + '/'))
throw new Error('overlapping mount keys') Prevention
- Keep URL mount keys as siblings, never nested
- Strip trailing slashes when generating keys programmatically
When it happens
Trigger: mounts: { '/assets': 'a', '/assets/img': 'b' } — '/assets/img' is nested under '/assets'; also duplicate keys after trailing-slash normalization like '/assets' and '/assets/'.
Common situations: Adding a nested URL scope for a different directory while the parent URL is already mounted; trailing-slash or basePath inconsistencies making two keys normalize identically; evolving config where an old mount was left in place.
Related errors
- mounts keys must be URL pathnames without query strings, fra
- mounts values must be relative to rootDir. Received "${fileR
- mounts values must not overlap. Received "${mount.fileRootVa
- Route module ${routesFile} must export a named "routes" valu
- Invalid route map value at "${location}". Expected a nested
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/25c31a0098dccb77.
Report an issue: GitHub.