vercel / vercel/next.js

Route groups / segments with non-Latin-1 characters crash with `InvalidCharacterError: Invalid character` (regression from Next 15)

Open
#97,890 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dynamic Routes Route Groups
Dominant language
JavaScript
Stars
142k
Forks
32.5k
Avg merge
2d 13h
Merged PRs (30d)
334

Description

Link to the code that reproduces this issue

https://github.com/hyonun321/nextjs-non-latin1-route-group-repro

To Reproduce
  1. npx create-next-app@latest repro --app --ts --no-tailwind --no-eslint

  2. Create a route group with a non-ASCII name and a page inside it:

    app/(안녕)/hello/page.tsx
    
    export default function Page() {
      return <h1>hello</h1>
    }
    
  3. next dev and open /hello500, terminal prints
    Error [InvalidCharacterError]: Invalid character

  4. next build → prerendering fails:

    Error [InvalidCharacterError]: Invalid character
    Error occurred prerendering page "/hello".
    Export encountered an error on /(안녕)/hello/page: /hello, exiting the build.
    

Same result with --webpack, so it is not bundler specific.

Current vs. Expected behavior
Next.js 15.5.9 Next.js 16.3.3
next dev/hello 200 500 InvalidCharacterError
next build ✓ static page generated fails in prerender
next start/hello 200 n/a (build fails)

Expected: same as Next 15 — a route group name is never part of the URL, so
its character set should not affect routing or rendering.

Also affects Japanese (日本), Cyrillic (тест), Latin-1 supplement (café)
and emoji (😀) — anything outside the Latin-1 range.

Root cause

encodeToFilesystemAndURLSafeString in
packages/next/src/shared/lib/segment-cache/segment-value-encoding.ts calls
btoa(value) on the raw segment name. btoa only accepts Latin-1 input and
throws a DOMException (InvalidCharacterError) otherwise. The segment cache
is now on by default, so every non-ASCII segment name hits this path.

The repo already has a UTF-8-safe variant of the same base64url encoding in
shared/lib/router/utils/cache-busting-search-param.ts (TextEncoder → binary
string → btoa).

Provide environment information
Operating System: Windows 11 Pro 10.0.26200
Binaries: Node 22.14.0
Relevant Packages: next 16.3.3, react 19.x
Which area(s) are affected? (Select all that apply)

Route Groups, Dynamic Routes

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local), next start (local)

Additional context

Note this is separate from #10084 (non-ASCII URL segments such as
app/소개/page.tsx/소개 returning 404), which reproduces on Next 15 as
well and is a routing/matching problem, not an encoding crash. This issue is
only about the Next 16 regression for non-ASCII route group / segment names
used in the segment cache key.

Fix PR: https://github.com/vercel/next.js/pull/97884

Previously filed as #97883 (auto-closed: body headings did not match the issue form) and #97886 (missing area labels). This one supersedes both; same content.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/next/src/shared/lib/segment-cache/segment-value-encoding.ts and the UTF-8-safe encoding variant in shared/lib/router/utils/cache-busting-search-param.ts. Run the linked reproduction with a non-ASCII route group using next dev and next build. Done means the route renders and prerenders successfully, matching the Next 15 behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nextjs
Domain
web-dev
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.