remix-run/remix · error · Error

Invalid route map value at

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.

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: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: 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)