remix-run/remix · error · CliError
RMX_ROUTE_MAP_LOADER_INVALID_JSON
RMX_ROUTE_MAP_LOADER_INVALID_JSON
Error message
Route-map loader returned invalid JSON
What it means
The route-map loader subprocess ran successfully but printed content that is not valid JSON on the channel the CLI parses. Anything app/routes.ts (or its imports) writes to stdout during loading corrupts the JSON handshake. The CLI therefore cannot extract the route map.
Source
Thrown at packages/cli/src/lib/errors.ts:113
title: 'Could not find a project root',
fix: 'Run this command inside a Remix project.',
},
remixConfigNotFound: {
code: 'RMX_CONFIG_NOT_FOUND',
title: 'Remix configuration not found',
fix: 'Check the --config path and try again.',
},
remoteSkillDataMissing: {
code: 'RMX_REMOTE_SKILL_DATA_MISSING',
title: 'Could not find remote Remix skill data',
},
routeMapLoaderFailed: {
code: 'RMX_ROUTE_MAP_LOADER_FAILED',
title: 'Route-map loader failed',
fix: 'Check app/routes.ts and make sure it exports a named `routes` value with a valid route map.',
},
routeMapLoaderInvalidJson: {
code: 'RMX_ROUTE_MAP_LOADER_INVALID_JSON',
title: 'Route-map loader returned invalid JSON',
fix: 'Check app/routes.ts and make sure route-map loading does not write extra output.',
},
routeMapLoaderSignal: {
code: 'RMX_ROUTE_MAP_LOADER_SIGNAL',
title: 'Route-map loader exited from a signal',
fix: 'Check app/routes.ts for side effects or runtime issues and try again.',
},
routeOwnerPlanUnresolved: {
code: 'RMX_ROUTE_OWNER_PLAN_UNRESOLVED',
title: 'Could not resolve a route owner plan',
},
routesFileNotFound: {
code: 'RMX_ROUTES_FILE_NOT_FOUND',
title: 'Could not find app/routes.ts',
fix: 'Run this command inside a Remix app that has app/routes.ts.',
},
targetDirectoryNotEmpty: {View on GitHub (pinned to 9696913134)
Solutions
- Remove console.log/process.stdout.write calls from app/routes.ts and any modules it imports at load time.
- Move logging into route handlers or lazy-loaded modules instead of module scope.
- If you need debug output while authoring routes, write to stderr or a file instead of stdout.
- Re-run the CLI command to confirm the JSON parses.
Example fix
// before
// app/routes.ts
console.log('building routes', config)
export const routes = config
// after
// app/routes.ts
export const routes = [
{ path: '/', file: 'routes/index.tsx' },
] Defensive patterns
Strategy: validation
Validate before calling
// Before loading, ensure route modules don't write to stdout
let src = await readFile('app/routes.ts', 'utf8')
if (/console\.log|process\.stdout\.write/.test(src)) {
throw new Error('route config writes to stdout')
} Try / catch
try {
let map = await loadRouteMap()
} catch (error) {
if (error.code === 'RMX_ROUTE_MAP_LOADER_INVALID_JSON') {
// strip stdout writes from route config imports
}
} Prevention
- Never console.log at module scope in app/routes.ts.
- Log from route config to stderr only.
When it happens
Trigger: app/routes.ts or one of its imports calling console.log/process.stdout.write at module scope; a dependency printing a banner; output buffering interleaving with the loader's JSON payload.
Common situations: Debug console.log statements left in route config files, noisy third-party imports (analytics SDKs, debug libraries), or polyfills that print during import.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- RMX_ROUTE_MAP_LOADER_INVALID_JSON
- hmr must be provided
- hmr requires watch mode
- Missing app/routes.ts path.
- Route module ${routesFile} must export a named "routes" valu
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/ce1bea87b109e493.
Report an issue: GitHub.