payloadcms / payloadcms/payload
GraphQL select projection drops sub-selections for aliased relationships and relationships nested in arrays/blocks
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 44.8k
- Forks
- 4.2k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 53
Description
Describe the Bug
When the GraphQL API resolves a relationship/upload field, it derives a select
projection from the GraphQL query (resolveSelect in @payloadcms/graphql). That
projection is silently dropped — and the relationship is fetched without its
sub-selection — in three cases:
-
Aliased relationship fields.
resolveSelectlooks the field up in the schema
withpath.key, which is the response key (the alias) rather than the real field
name. An aliased relationship (myAlias: myRelation { ... }) is not found in the
field map, so its sub-selection is not projected. -
Relationships nested inside arrays / blocks / uploads.
formattedNameResolver
only attachesextensions.fieldwhen the GraphQL name differs from the data name.
Sub-fields whose name is already camelCase (typical inside arrays/blocks) get no
extensions.field, soresolveSelectcannot map them back to a data field and the
traversal breaks. -
Relationships inside a block (union).
buildSelectTreenests a block's
sub-selection under the block slug, butresolveSelect's traversal never pushes the
block slug onto its lookup path, so the paths do not line up.
On the SQL adapters (postgres/sqlite) the result is that the nested relationship comes
back id-only (or null), losing the queried sub-fields.
Link to reproduction
Added as an integration test in test/collections-graphql (see linked PR).
Which area(s) are affected?
area: core, GraphQL
Environment
- Payload version: 3.x (reproduced on latest 3.88.0)
- Adapter:
@payloadcms/db-postgres(and@payloadcms/db-sqlite)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with resolveSelect in @payloadcms/graphql, then trace formattedNameResolver and buildSelectTree to compare GraphQL response keys with data-field paths. Use the integration tests in test/collections-graphql as the reproduction point. Done means aliased relationships and relationships in arrays, blocks, uploads, and block unions retain their queried sub-selections on the SQL adapters.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, postgresql, sqlite, typescript
- Domain
- api, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100