Skip to content

[Postgres] sort by join field crashes on versioned collection with custom text id (integer = character varying) #16390

@nathanbowang

Description

@nathanbowang

Describe the Bug

When all three of the following are true on Postgres:

  1. the collection has versions: { drafts: true }
  2. the collection uses a custom text id (e.g. nanoid)
  3. 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?

  • area: core
  • db: postgres

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions