Connection Fields in Query are parsed to `undefined` even though network response has data in those fields
Hooks used
-
useLazyLoadQuery -
usePaginationFragment
Versions
- React:
19.0.0-rc-66855b96-20241106 - React-Relay:
18.2.0
Issue Description
When using loadNext from the usePaginationFragment hook, connection fields are parsed as undefined - But in the network response exist correctly.
Any data fetched initially is correctly structured via the Server response - this only happens with PAGINATED data.
This seems to be a regression after updating to the latest version of Relay. This setup was working previously.
I've been able to narrow down one of the triggers for it.
If i have a connection like friends(), if i add a VARIABLE of first - the bug appears.
Error:
friends(first: $friendsFirst)
Works:
friends(first: 20)
Example of Data
Retrieved from Server:
{
"id": "123",
"friends": { "edges": [] }
}
Returned from usePaginationFragment:
{
"id": "123",
"friends": undefined
}
Example of Query
Wrapper Query:
query HomeQuery($first: Int = 20, $cursor: Cursor, $where: WhereInput = {}, ...bunchOfArgs){
...HomeFragment @arguments(first: $first, cursor: $cursor, where: $where, ...bunchOfArgs: $...bunchOfArgs)
}
Fragment:
fragment HomeFragment on Query
@argumentDefinitions(
first: { type: "Int", defaultValue: 20 }
cursor: { type: "Cursor" }
where: { type: "WhereInput", defaultValue: {} }
...bunchOfArgsDefs
)
@refetchable(queryName: "HomePaginationQuery") {
objects(first: $first, after: $cursor, where: $where)
@connection(key: "HomeConnection_objects", filters: ["where"]){
edges {
node {
id
friends(first: 20 # Changing this to a variable causes the bug to appear){
edges {
node {
id
}
}
}
}
}
}
}
@KieranTH do you have the full response payload to share for the loadNext that parsed to undefined? Including
{
data: {},
errors: [] // (if any errors exist)
}
@KieranTH do you have the full response payload to share for the loadNext that parsed to undefined? Including
{ data: {}, errors: [] // (if any errors exist) }
There are no errors in response by the backend.
The response looks something like this:
{
data: {
objects: {
edges: [
{
node: {
"id": "123",
"friends": { "edges": [] }
}
}
]
}
}
}
I've actually been able to narrow it down fully.
When a default value isn't given to the first variable IN THE WRAPPER QUERY, the bug appears.
BROKEN:
HomeQuery($first: Int = 20, $cursor: Cursor, $where: WhereInput = {}, $friendFrist: Int)
WORKING:
HomeQuery($first: Int = 20, $cursor: Cursor, $where: WhereInput = {}, $friendFirst: Int = 20)
Even though I have a default set in the Fragment Arguments:
{
friendFirst: {type: "Int", defaultValue: 20}
}
Any ideas why this could cause such weird behaviour?
Interesting. Thanks for the report. So, if I understand correctly, the bug triggers when:
- The
firstargument to your connection field is provided by a fragment variable with a default value provided (first: { type: "Int", defaultValue: 20 } - You are passing the fragment to the query using a query variable that does not have a default value
- You make an initial query (With what variables passed?)
- You paginate (with no variables passed?)
If all these things are true, you end up with "friends": undefined in your component?
I'm a little confused by the inclusion of $first and $firstFriend and how they actually fit together in the real example.
Cache keys in the store are computed based on a field's name as well as a serialized form of the variables passed to that field. I suspect there's some disagreement between one or more of:
- RelayResponseNormalizer (which uses the generated artifact for the query)
- Connection handler
- RelayReader (which uses the generated artifact for the fragment).
Perhaps somehow this combination of variables/defaults triggers a bug where they end up computing different cache keys? A snapshot of what's in the store before/after you issue the pagination query might help us understand what's gone wrong here.
The next step here would be to create a reproduction of the issue as a test. Probably following the examples given here: https://github.com/facebook/relay/blob/main/packages/react-relay/relay-hooks/tests/usePaginationFragment-test.js
I'm facing this issue as well in react-relay 19 where non-deterministically a node off of which I'm fetching a connection is undefined. It doesn't happen consistantly. Happy to provide any details.
@mikeldking Are you using React Activity with relay hook ? I also meet same issue during using activity.
so I also try to figure out that root cause.