{"record":{"id":"fe57908cd4aeb7ef","repo":"remix-run/remix","slug":"rmx-route-map-loader-invalid-json-fe5790","errorCode":"RMX_ROUTE_MAP_LOADER_INVALID_JSON","errorMessage":"Route-map loader returned invalid JSON.","messagePattern":"Route-map loader returned invalid JSON\\.","errorType":"exception","errorClass":"CliError","httpStatus":null,"severity":"error","filePath":"packages/cli/src/lib/route-map.ts","lineNumber":138,"sourceCode":"\n  if (exitResult.signal != null) {\n    throw routeMapLoaderSignal(exitResult.signal)\n  }\n\n  if (exitResult.code !== 0) {\n    let message = stderr.trim()\n    if (message.length === 0) {\n      message = 'Route-map loader failed.'\n    }\n\n    throw routeMapLoaderFailed(message)\n  }\n\n  let parsed: unknown\n  try {\n    parsed = JSON.parse(stdout)\n  } catch {\n    throw routeMapLoaderInvalidJson()\n  }\n\n  return assertRawRouteTree(parsed)\n}\n\nfunction decorateRouteTree(\n  rawTree: RawRouteTreeNode[],\n  ownership: ControllerOwnership,\n): RouteTreeNode[] {\n  let subtreesByRouteName = new Map(\n    ownership.subtrees.map((subtree) => [subtree.routeName, subtree]),\n  )\n  let directoriesByRouteName = new Map(\n    ownership.routeDirectories.map((directory) => [directory.routeName, directory]),\n  )\n\n  return decorateRouteTreeWithLookup(rawTree, subtreesByRouteName, directoriesByRouteName)\n}","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/cli/src/lib/route-map.ts#L120-L156","documentation":"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.","triggerScenarios":"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.","commonSituations":"Console.log calls at module scope in routes.ts or imported config polluting stdout; patched/mismatched CLI versions where the worker protocol changed.","solutions":["Remove or redirect any console.log in modules loaded by routes.ts (write to stderr instead)","Ensure no middleware/plugin writes to stdout during route-map loading","Reinstall to align CLI and worker versions so the JSON protocol matches"],"exampleFix":"// before (app/routes.ts module scope)\nconsole.log('routes loaded')\n// after\nconsole.error('routes loaded')","handlingStrategy":"try-catch","validationCode":"const looksLikeJson = (stdout: string): boolean =>\n  stdout.trimStart().startsWith('[') || stdout.trimStart().startsWith('{')","typeGuard":"const isJsonRouteTree = (value: unknown): value is unknown[] =>\n  typeof value === 'object' && value !== null && 'length' in value","tryCatchPattern":"catch (error) {\n  if (error instanceof Error && error.code === 'RMX_ROUTE_MAP_LOADER_INVALID_JSON') {\n    // instruct user to remove stdout writes from routes modules\n  }\n  throw error\n}","preventionTips":["Never console.log at module scope in route modules; use console.error","Pin the CLI and worker versions together in your lockfile"],"tags":["cli","routes","json","subprocess"],"backgroundTag":"invalid-json-response","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}