payloadcms / payloadcms/payload

[Admin UI] List view columns query param re-encodes infinitely on refresh, eventually exceeding URL length limits

Open
#16,659 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area: core stale v3
Dominant language
TypeScript
Stars
44.8k
Forks
4.2k
Avg merge
2d 21h
Merged PRs (30d)
53

Description

Describe the Bug

The columns query parameter in collection list views accumulates a new layer of JSON.stringify encoding on every page refresh after a specific navigation sequence.

The escape depth doubles indefinitely with each refresh and after ~20 refreshes the URL exceeds Vercel's request size limit (~14KB) and the admin panel becomes inaccessible returning a 414 uri too long error.

/admin/collections/products?columns=%22%5C%22%5C%5C%5C%22%5C%5C%5C%5C%5C%5C%5C%22...
Link to the code that reproduces this issue

https://github.com/wayz9/payloadcms-uri-too-long

Reproduction Steps

Reproduced on a fresh install of the official Payload starter, version 3.84.1.

  1. Open the admin panel and navigate to any collection list view (e.g. /admin/collections/pages).
  2. Open the Columns dropdown in the toolbar and toggle on an extra column. The URL now contains a columns query parameter with the customized array.
  3. Click any row to open that documents edit view.
  4. Use the browser back button to return to the list view.
  5. Click any column header to apply a sort. The URL now has sort= appended, and columns has gained its first extra layer of escaping (the array is now wrapped as a quoted JSON string).
  6. Refresh the page. The columns parameter gains another escape layer. Refresh again. And again. Each refresh roughly doubles the backslash count in the encoded columns value.

Video

https://github.com/user-attachments/assets/223f650b-298e-4742-b678-2c3adc9da5b6

Which area(s) are affected?

area: core

Environment Info
Binaries:
  Node: 24.14.0
  npm: 11.9.0
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  payload: 3.84.1
  next: 16.2.6
  @payloadcms/db-mongodb: 3.84.1
  @payloadcms/graphql: 3.84.1
  @payloadcms/live-preview: 3.84.1
  @payloadcms/live-preview-react: 3.84.1
  @payloadcms/next/utilities: 3.84.1
  @payloadcms/plugin-form-builder: 3.84.1
  @payloadcms/plugin-nested-docs: 3.84.1
  @payloadcms/plugin-redirects: 3.84.1
  @payloadcms/plugin-search: 3.84.1
  @payloadcms/plugin-seo: 3.84.1
  @payloadcms/richtext-lexical: 3.84.1
  @payloadcms/translations: 3.84.1
  @payloadcms/ui/shared: 3.84.1
  react: 19.2.6
  react-dom: 19.2.6
Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Thu Jun  5 18:30:46 UTC 2025
  Available memory (MB): 30891
  Available CPU cores: 32

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 the linked reproducer and trace the columns query parameter through the collection list view, Columns dropdown, row navigation, browser back navigation, sorting, and refresh. Confirm the behavior on a fresh Payload starter, then verify that repeated refreshes no longer add escaping and the URL remains stable without exceeding request limits.

Written by the indexing model from the issue text.

Assessment

Tech stack
next.js, react, typescript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.