remix-run/remix · error · AssetServerCompilationError
FILE_OUTSIDE_MOUNTS
FILE_OUTSIDE_MOUNTS
Error message
File ${identityPath} is outside all configured mounts. What it means
After a file passes the access check, the compiler must map its identity path to a servable URL via `args.routes.toUrlPathname(identityPath)`. A null/undefined return means the file does not live under any configured mount, so there is no URL namespace it can be served from, and compilation fails with FILE_OUTSIDE_MOUNTS.
Source
Thrown at packages/assets/src/lib/files/compiler.ts:571
})
}
if (!args.isAllowed(identityPath)) {
throw createAssetServerCompilationError(
`File "${identityPath}" is not allowed by the asset server access configuration. ` +
`Add a matching allowFiles or allowPackages rule, or remove a conflicting denyFiles rule.`,
{
code: 'FILE_NOT_ALLOWED',
},
)
}
let stableUrlPathname = args.routes.toUrlPathname(identityPath)
if (!stableUrlPathname) {
throw createAssetServerCompilationError(
`File ${identityPath} is outside all configured mounts.`,
{
code: 'FILE_OUTSIDE_MOUNTS',
},
)
}
return {
identityPath,
stableUrlPathname,
}
}
export function createResponseForFile(
result: FileCompileResult,
options: {
cacheControl: string
ifNoneMatch: string | null
method: string
},
): Response {View on GitHub (pinned to 9696913134)
Solutions
- Add or extend a mount so the file's directory is covered, e.g. mount the assets directory in the file routes config
- Align overly-broad allowFiles globs with the actual mount roots so allowed files are always servable
- If the file comes from a linked/workspace package, mount that package's directory as well
Example fix
// before
routes: createFileRoutes({ mounts: { '/assets': 'app/assets' } })
// file lives in app/private/logo.svg → outside all mounts
// after
routes: createFileRoutes({ mounts: { '/assets': 'app/assets', '/private': 'app/private' } }) Defensive patterns
Strategy: validation
Validate before calling
// Ensure each identity path falls under a mount root before compiling:
for (const file of filesToServe) {
if (!mounts.some(([, root]) => isWithin(root, file))) {
throw new Error(`configure a mount covering ${file}`)
}
} Type guard
function isWithin(root: string, path: string): boolean {
const rel = path.slice(root.length)
return path.startsWith(root) && (rel === '' || rel.startsWith('/'))
} Try / catch
try {
const resolved = compiler.resolvedFile(file)
} catch (error) {
if (error?.code === 'FILE_OUTSIDE_MOUNTS') {
// add a mount for the file's directory, or stop serving it
}
throw error
} Prevention
- Make allow rules a subset of mount coverage — allowed implies servable
- Mount workspace/symlinked package directories explicitly
When it happens
Trigger: A file passes allowFiles/allowPackages validation but its directory is not covered by any mount configured on the file routes (e.g. allowed via a broad glob but the mount only covers a subdirectory, or the file resolves through a symlink outside all mount roots).
Common situations: Adding an allowFiles rule broader than the mounts (allowing files the mounts can't serve); moving assets to a new directory without adding a mount; symlinked dependencies or workspace packages whose real path falls outside every configured mount root.
Related errors
- FILE_NOT_ALLOWED
- FILE_TRANSFORM_RESULT_INVALID
- FILE_OUTSIDE_MOUNTS
- hmr must create a channel with a close function
- basePath must be a string
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/e9e2652b16b510f5.
Report an issue: GitHub.