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 exited successfully but the JSON it printed to stdout could not be parsed by JSON.parse. The contract requires the loader to emit a JSON route tree on stdout; anything else (logs, partial output, empty stdout) triggers this error.

Source

Thrown at packages/cli/src/lib/route-map.ts:138

  if (exitResult.signal != null) {
    throw routeMapLoaderSignal(exitResult.signal)
  }

  if (exitResult.code !== 0) {
    let message = stderr.trim()
    if (message.length === 0) {
      message = 'Route-map loader failed.'
    }

    throw routeMapLoaderFailed(message)
  }

  let parsed: unknown
  try {
    parsed = JSON.parse(stdout)
  } catch {
    throw routeMapLoaderInvalidJson()
  }

  return assertRawRouteTree(parsed)
}

function decorateRouteTree(
  rawTree: RawRouteTreeNode[],
  ownership: ControllerOwnership,
): RouteTreeNode[] {
  let subtreesByRouteName = new Map(
    ownership.subtrees.map((subtree) => [subtree.routeName, subtree]),
  )
  let directoriesByRouteName = new Map(
    ownership.routeDirectories.map((directory) => [directory.routeName, directory]),
  )

  return decorateRouteTreeWithLookup(rawTree, subtreesByRouteName, directoriesByRouteName)
}

View on GitHub (pinned to 9696913134)

Solutions

  1. Remove or redirect any console.log in modules loaded by routes.ts (write to stderr instead)
  2. Ensure no middleware/plugin writes to stdout during route-map loading
  3. Reinstall to align CLI and worker versions so the JSON protocol matches

Example fix

// before (app/routes.ts module scope)
console.log('routes loaded')
// after
console.error('routes loaded')
Defensive patterns

Strategy: try-catch

Validate before calling

const looksLikeJson = (stdout: string): boolean =>
  stdout.trimStart().startsWith('[') || stdout.trimStart().startsWith('{')

Type guard

const isJsonRouteTree = (value: unknown): value is unknown[] =>
  typeof value === 'object' && value !== null && 'length' in value

Try / catch

catch (error) {
  if (error instanceof Error && error.code === 'RMX_ROUTE_MAP_LOADER_INVALID_JSON') {
    // instruct user to remove stdout writes from routes modules
  }
  throw error
}

Prevention

When it happens

Trigger: App code (or a plugin/preset) writing to stdout during route-map loading, corrupting the JSON stream; a loader version mismatch emitting a different format; empty stdout after a silent failure.

Common situations: Console.log calls at module scope in routes.ts or imported config polluting stdout; patched/mismatched CLI versions where the worker protocol changed.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


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