remix-run/remix · error · Error

Route-map loader returned an invalid tree.

Error message

Route-map loader returned an invalid tree.

What it means

The route-map loader runs a worker that JSON-serializes the parsed route tree back to the main process. If the deserialized payload is not an array, this assertion fails — almost always a version mismatch or corrupted IPC, not a user config issue.

Source

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

    let directory = directoriesByRouteName.get(rawNode.name)

    if (directory == null) {
      throw routeOwnerPlanUnresolved(rawNode.name)
    }

    return {
      exists: directory.exists,
      kind: 'directory',
      path: directory.directoryPath,
    }
  }

  throw routeOwnerPlanUnresolved(rawNode.name)
}

function assertRawRouteTree(value: unknown): RawRouteTreeNode[] {
  if (!Array.isArray(value)) {
    throw new Error('Route-map loader returned an invalid tree.')
  }

  return value.map((entry) => assertRawRouteTreeNode(entry))
}

function assertRawRouteTreeNode(value: unknown): RawRouteTreeNode {
  if (typeof value !== 'object' || value == null) {
    throw new Error('Route-map loader returned an invalid route node.')
  }

  let key = Reflect.get(value, 'key')
  let name = Reflect.get(value, 'name')
  let kind = Reflect.get(value, 'kind')
  let children = Reflect.get(value, 'children')

  if (typeof key !== 'string' || typeof name !== 'string') {
    throw new Error('Route-map loader returned a route node without a valid name.')
  }

View on GitHub (pinned to 9696913134)

Solutions

  1. Reinstall dependencies (`rm -rf node_modules && pnpm install`) to align CLI versions
  2. Deduplicate remix/CLI packages: `pnpm why remix` and pin a single version
  3. If mocking in tests, return a RawRouteTreeNode[] array from the mock
Defensive patterns

Strategy: try-catch

Validate before calling

if (!Array.isArray(await workerResult)) throw new Error('unexpected worker payload')

Type guard

const isTree = (v: unknown): v is unknown[] => Array.isArray(v)

Try / catch

try { await loadRawRouteMap(...) } catch (e) { if (String(e.message).includes('invalid tree')) { await cleanReinstall() } throw e }

Prevention

When it happens

Trigger: loadRawRouteMap receives a worker response whose top-level value is not an array (e.g. an object, string, or error payload parsed as data).

Common situations: Mixed CLI versions in node_modules (worker from one remix version, spawner from another); pnpm hoisting weirdness; manually mocking the worker response in tests.

Related errors


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