payloadcms / payloadcms/payload

GraphQL select projection drops sub-selections for aliased relationships and relationships nested in arrays/blocks

Open
#18,141 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Bug
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:

  1. Aliased relationship fields. resolveSelect looks the field up in the schema
    with path.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.

  2. Relationships nested inside arrays / blocks / uploads. formattedNameResolver
    only attaches extensions.field when the GraphQL name differs from the data name.
    Sub-fields whose name is already camelCase (typical inside arrays/blocks) get no
    extensions.field, so resolveSelect cannot map them back to a data field and the
    traversal breaks.

  3. Relationships inside a block (union). buildSelectTree nests a block's
    sub-selection under the block slug, but resolveSelect'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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.