remix-run/remix · error · AssetServerCompilationError

FILE_OUTSIDE_MOUNTS

FILE_OUTSIDE_MOUNTS

Error message

File ${record.identityPath} is outside all configured mounts.

What it means

The asset transform pipeline maps each module's identity path to a stable URL pathname via the configured route mounts. When `args.routes.toUrlPathname(record.identityPath)` returns a falsy value, the file cannot be attributed to any mount, so the transform aborts with FILE_OUTSIDE_MOUNTS. This protects the asset server from serving modules whose URL identity cannot be resolved.

Source

Thrown at packages/assets/src/lib/scripts/transform.ts:230

        },
      }
    }
    return {
      ok: false,
      error: toTransformFailedError(error, resolvedPath),
      tracking: {
        trackedFiles,
      },
    }
  }

  try {
    let stableUrlPathname = args.routes.toUrlPathname(record.identityPath)
    if (!stableUrlPathname) {
      throw createAssetServerCompilationError(
        `File ${record.identityPath} is outside all configured mounts.`,
        {
          code: 'FILE_OUTSIDE_MOUNTS',
        },
      )
    }

    let analysis = await analyzeModuleSource(sourceText, resolvedPath, transformOptions, {
      define: args.define ?? undefined,
      minify: args.minify,
      loaders: args.loaders,
      moduleUrl: stableUrlPathname,
      sourceMaps: args.sourceMaps ?? undefined,
      target: args.target ?? undefined,
    })

    analysis.unresolvedImports = analysis.unresolvedImports.filter(
      (unresolved) => !args.externalSet.has(getDisplayImportSpecifier(unresolved.specifier)),
    )

    if (mayContainCommonJSModuleGlobals(sourceText) && isCommonJS(analysis.rawCode)) {

View on GitHub (pinned to 9696913134)

Solutions

  1. Check which mounts your routes/mount configuration defines and add an entry that covers the failing identityPath
  2. Verify the file's absolute path (record.identityPath) against the mount prefixes — look for case sensitivity or symlink mismatches
  3. If the file is intentionally outside mounts (e.g. node_modules or generated assets), exclude it from the transform set instead of mounting it
  4. Ensure a custom toUrlPathname implementation returns a pathname for every record you pass to transformModule

Example fix

// before
routes.toUrlPathname('/packages/ui/src/button.ts') // => undefined → error

// after
// register the packages/ui directory as a mount so its files resolve to stable URLs
mounts: [{ root: path.resolve('packages/ui'), prefix: '/ui' }]
Defensive patterns

Strategy: validation

Validate before calling

const url = args.routes.toUrlPathname(record.identityPath)
if (!url) {
  throw new Error(`Refusing to transform ${record.identityPath}: not under any mount`)
}

Type guard

function isInsideMounts(identityPath: string, routes: { toUrlPathname(p: string): string | undefined }): boolean {
  return Boolean(routes.toUrlPathname(identityPath))
}

Try / catch

catch (e) { if (isAssetServerCompilationError(e) && e.code === 'FILE_OUTSIDE_MOUNTS') { /* skip file or register mount */ } else throw e }

Prevention

When it happens

Trigger: Calling transformModule (directly or via transformModuleResult) for a record whose identityPath is not covered by any mount configured on the routes object. This happens when the file lives outside directories registered as mounts, or when routes.toUrlPathname returns undefined/null/'' for that path.

Common situations: Adding new source directories (e.g. a workspace package or vendor folder) without registering a corresponding mount; typos or case-mismatch in mount paths; moving files outside the app source root; custom routes implementations that only map routes/ but not shared lib directories.

Related errors


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