Describe the Bug
When all three of the following are true on Postgres:
- the collection has
versions: { drafts: true }
- the collection uses a custom text id (e.g. nanoid)
- the user sorts the admin list view by a
join field
…the entire list view crashes with:
operator does not exist: integer = character varying
The user cannot recover from the admin UI — Payload persists the broken sort into payload_preferences and re-applies it on every page load, so the list view is permanently inaccessible until someone manually updates the row in the database.
Link to the code that reproduces this issue
https://gist.github.com/nathanbowang/d593dc603e3da03ec5cb0f7871da6561
Reproduction Steps
See the gist. tl;dr: with the config above, calling
await payload.find({
collection: 'text-id-categories-versions',
draft: true,
sort: 'relatedSingle', // or 'relatedMany'
})
reproduces the crash. The same path is hit from the admin UI by clicking the join column header to sort.
Which area(s) are affected?
Environment Info
Payload: 3.81.0 (also reproduces on current main)
Database: @payloadcms/db-postgres (PostgreSQL 16)
Next.js: 15.4.11
Node.js: 24.11.1
Root cause
In packages/drizzle/src/queries/getTableColumnFromPath.ts, both branches of case 'join' build the join condition off adapter.tables[*].id. On a versions table (*_v), id is the version-row PK (always integer), not the parent document id. The joined _rels / target column references the parent document id, which is varchar for custom text ids — hence the integer = character varying mismatch. The fix is to use the versions table's parent column (mapped from parent_id) as the join key whenever the source table is a versions table.
I have a patch + regression test ready and will open a PR.
Describe the Bug
When all three of the following are true on Postgres:
versions: { drafts: true }joinfield…the entire list view crashes with:
The user cannot recover from the admin UI — Payload persists the broken sort into
payload_preferencesand re-applies it on every page load, so the list view is permanently inaccessible until someone manually updates the row in the database.Link to the code that reproduces this issue
https://gist.github.com/nathanbowang/d593dc603e3da03ec5cb0f7871da6561
Reproduction Steps
See the gist. tl;dr: with the config above, calling
reproduces the crash. The same path is hit from the admin UI by clicking the
joincolumn header to sort.Which area(s) are affected?
Environment Info
Root cause
In
packages/drizzle/src/queries/getTableColumnFromPath.ts, both branches ofcase 'join'build the join condition offadapter.tables[*].id. On a versions table (*_v),idis the version-row PK (always integer), not the parent document id. The joined_rels/ target column references the parent document id, which isvarcharfor custom text ids — hence theinteger = character varyingmismatch. The fix is to use the versions table'sparentcolumn (mapped fromparent_id) as the join key whenever the source table is a versions table.I have a patch + regression test ready and will open a PR.