obsidian/wiki/payloadcms/troubleshooting.md
2026-05-15 16:50:41 +01:00

4.6 KiB

title aliases tags sources created updated
Payload CMS — Troubleshooting Common Issues
payload-troubleshooting
payload-debug
payload-common-errors
payloadcms
troubleshooting
dependencies
auth
database
hmr
raw/troubleshooting__troubleshooting.md
2026-05-15 2026-05-15

Dependency Mismatches

All payload and @payloadcms/* packages must be on exactly the same version and installed only once. Duplicate versions cause broken React context:

TypeError: Cannot destructure property 'config' of...

Diagnose duplicates

# pnpm
pnpm why @payloadcms/ui

# Any package manager
find node_modules -name package.json -exec grep -H '"name": "@payloadcms/ui"' {} \;

Check react and react-dom the same way — a second copy causes identical symptoms.

Note: @payloadcms/ui ships two bundles by design — dual paths in pnpm output are normal.

Correct import paths in Admin Panel

Inside Payload Admin UI, only import from:

  • @payloadcms/ui
  • @payloadcms/ui/rsc
  • @payloadcms/ui/shared

Deep imports like @payloadcms/ui/elements/Button are for your frontend only, outside of the Admin Panel.

Fix steps (pnpm)

  1. Pin exact versions — remove ^ and ~ from payload, @payloadcms/*, react, react-dom
  2. Delete node_modules
  3. pnpm install

If still broken:

pnpm store prune   # clean global store
# Delete lockfile + node_modules, then:
pnpm install
pnpm dedupe

Last resort: add Webpack alias resolve.alias['react'] = path.resolve('./node_modules/react') until root cause is fixed.

Monorepos

Monorepo pitfall: package managers hoist dependencies differently per package, causing multiple instances.

  • Pin payload, @payloadcms/*, next, react, react-dom at monorepo root
  • Delete .next/, node_modules/, lockfile, then re-install
  • Watch for: useUploadHandlers must be used within UploadHandlersProvider — next version mismatch

"Unauthorized" on Login

Unauthorized, you must be logged in to make this request

Means the auth cookie is not being set or accepted. Check:

  • CORS — avoid '*'; list explicit allowed domains
  • CSRF — if configured, whitelist your domain
  • Cookie settings — if domain is set, verify it's not misconfigured

Debug via Network tab

  1. Open DevTools → Network tab
  2. Perform login
  3. Inspect the login response — look for Set-Cookie header
  4. Browser shows ⚠️ icon if cookie was rejected — hover to read the reason

--experimental-https HMR WebSocket Issue

Using --experimental-https breaks HMR WebSocket (ws:// vs wss://).

Fix — simple case:

USE_HTTPS=true

Fix — dynamic URL:

PAYLOAD_HMR_URL_OVERRIDE=wss://localhost:3000/_next/webpack-hmr

Database Password Encoding

Special characters in DB password cause silent connection failures:

Cannot read properties of undefined (reading 'searchParams')
Error: cannot connect to Postgres. Details: ...

Fix: URI-encode the password:

encodeURIComponent(yourPassword)

Set the encoded string in the DATABASE_URI connection string.

First verify the connection works outside Payload (e.g. Beekeeper Studio) to rule out network issues.


Key Takeaways

  • Same version, one copy — any @payloadcms/* or react duplicate breaks context hooks with cryptic errors
  • pnpm dedupe + store prune — go-to when re-install alone doesn't fix it
  • Monorepo root deps — install Payload packages at root level to avoid hoist conflicts
  • Auth "Unauthorized" — 90% a cookie domain/CORS/CSRF misconfiguration; debug with Network tab
  • HTTPS in dev — set USE_HTTPS=true or PAYLOAD_HMR_URL_OVERRIDE to fix HMR WebSocket protocol mismatch
  • DB special chars — always encodeURIComponent passwords with @, #, % etc. in connection strings


Sources