remix-run/remix · error · Error

Invalid route map value at "${name}". Expected a route or ne

Error message

Invalid route map value at "${name}". Expected a route or nested route object.

What it means

Each entry inside a group object must be either a leaf route object or another nested group object. Anything else (string, number, array, null) at that key triggers this error with the offending key name.

Source

Thrown at packages/cli/src/lib/load-route-map-worker.ts:80

          children: [],
          key,
          kind: 'route',
          method: routeLeaf.method,
          name,
          pattern: routeLeaf.pattern,
        } satisfies RawRouteTreeNode
      }

      if (isPlainObject(entryValue)) {
        return {
          children: normalizeRouteGroup(entryValue, nameSegments, seen),
          key,
          kind: 'group',
          name,
        } satisfies RawRouteTreeNode
      }

      throw new Error(
        `Invalid route map value at "${name}". Expected a route or nested route object.`,
      )
    })
  } finally {
    seen.delete(value)
  }
}

function readRouteLeaf(value: unknown): { method: string; pattern: string } | undefined {
  if (typeof value !== 'object' || value == null) return undefined

  let method = Reflect.get(value, 'method')
  let pattern = Reflect.get(value, 'pattern')
  if (typeof method !== 'string' || !hasToString(pattern)) return undefined

  return { method, pattern: pattern.toString() }
}

View on GitHub (pinned to 9696913134)

Solutions

  1. Convert the offending entry to a route object or nested group object
  2. Move non-route metadata out of the routes map into separate constants
  3. Check the key named in the message and fix only that entry

Example fix

// before
export let routes = { pages: { home: 'home.tsx' } }
// after
export let routes = { pages: { home: { file: 'home.tsx' } } }
Defensive patterns

Strategy: type-guard

Validate before calling

for (let [key, value] of Object.entries(group)) {
  if (!isPlainObject(value)) throw new Error(`invalid entry ${key}`)
}

Type guard

function isRouteEntry(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v)
}

Prevention

When it happens

Trigger: A property of a route group that is not a route/group object, e.g. `{ pages: { home: 'home.tsx' } }` or extra metadata like `{ layout: 42 }`.

Common situations: Attaching helper flags, comments-as-keys, or string file names directly inside groups; mixing conventions from other config formats.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


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