---
title: "payload-auth login conflict"
description: "Keep payload-auth's collection apart from Systhema's users collection."
url: https://docs.systhema.app/next/payload/troubleshooting/payload-auth
version: unreleased (main)
docs_index: https://docs.systhema.app/next/llms.txt
---

payload-auth is an optional third-party plugin that some projects add to Systhema.
Systhema does not install, configure or test it. This page documents a known
conflict; it is not a support commitment.

In a dual-auth setup, Payload owns CMS admins and Better Auth owns application
accounts. payload-auth 1.9.x takes over the Payload admin login and queries `role`
on the admin users collection, while Systhema's collection stores `roles`. This
can break admin login while the public site remains healthy.

## Collection ownership

- Payload owns the Systhema `users` collection and the admin login. Its `roles` field
  is a `select` with `hasMany: true`; authorization uses those roles and capabilities.
  Keep `admin.user` pointing to this collection, including if you customize its slug.
- Better Auth owns application accounts in a different collection, for example
  `members`. A member session must not grant CMS access. Do not point
  `admin.user` at the application collection to avoid the bootstrap query.
- Keep the application login, session handling and access rules separate from the
  Payload admin. Test both anonymous and authenticated access to each system.

## Legacy recovery with payload-auth 1.8.4

An existing dual-auth project can retain the pre-1.9 admin behavior by pinning
`payload-auth` to **exactly `1.8.4`** and setting `disableDefaultPayloadAuth: false`.
The declared range `>=1.8.4 <1.9.0` also prevents a 1.9 upgrade, but only 1.8.4 was
inspected for this write-up. `^1.8.4` can resolve to 1.9.4 when the lockfile is
regenerated, so it is not a safe pin.

Check the entire dependency stack first. The published 1.8.4 package requires
Next.js `>=15.4.8 <16`, whereas 1.9.4 declares `>=15.4.8 <17`. Both accept Payload
`>=3.69.0 <4`. The Systhema starter uses Next.js 16, which is outside 1.8.4's
published peer range. Pinning 1.8.4 alone cannot establish compatibility. Do not
suppress peer errors or downgrade a project's Next.js version as an automatic
auth fix.

For an existing project whose dependencies satisfy the 1.8.4 peers:

```bash
pnpm add --save-exact payload-auth@1.8.4
```

Keep the relevant legacy plugin options explicit:

```ts
betterAuthPlugin({
  disableDefaultPayloadAuth: false,
  users: { slug: 'members' },
  // Keep the project's existing Better Auth options and access rules.
})
```

Here `users.slug` is payload-auth's application-user collection. It is separate
from Payload's `admin.user`, which remains the Systhema CMS users collection.
Preserve any other collection overrides the project needs. This is a versioned
configuration fragment, not a complete integration recipe or an end-to-end test.

Commit the updated lockfile. Regenerate Payload types and the import map using the
project's existing scripts, then test CMS login/logout, an existing admin editing
a document, member signup/login/logout, and denial of CMS access to members.
Check `/admin` while logged out as well as the public site in deployment smoke tests.
A successful public health endpoint does not prove the admin can render.

## Why a role alias is unsafe

The published 1.9.4 implementation calls `applyBetterAuthAdminConfig` whenever
`betterAuthPlugin` is enabled. In 1.8.4 the corresponding admin override is guarded
by `disableDefaultPayloadAuth`. In 1.9.4 the replacement login view reads
`config.admin.user` and counts records with `role` equal to the configured default
admin role, which defaults to `admin`. Systhema defines `roles`, not `role`, so the
query fails for its standard schema.

If an added, queryable `role` field is empty, the count becomes zero. The login view
then finds or creates an admin invitation and redirects the anonymous visitor to
admin signup with its token. The signup view validates that invitation token. This
confirms the bootstrap redirect risk; it is not a claim that every customized
project would allow a completed privilege escalation.

Populating an alias would only address that query. It would still leave two auth
systems disagreeing about login ownership, sessions and authorization. An alias
is not a fix for this conflict. Any project integrating these auth systems needs
to validate existing admins, fresh installations, signup authorization, session
separation and role changes independently.
