Hi everyone,
Firstly, apologies if this is the wrong repository. I'm not entirely sure whether this belongs here or on the Hot Chocolate repository.
I couldn't find an existing GitHub issue describing this scenario, although it's entirely possible that I'm missing something or that I'm using the framework incorrectly.
Environment
Hot Chocolate – 15.1.14
React – 18.1.0
react-relay – 16.2.0
relay-runtime – 16.2.0
What I'm trying to achieve
I have a page that displays a list of items using a Relay connection and a MUI DataGrid.
A user can create a new item from a modal dialog. The modal performs a Relay mutation, and I use Relay's declarative mutation directive @prependNode so that the newly created node is automatically inserted into the existing Relay connection.
The DataGrid itself contains no local state—it simply renders whatever exists in the Relay store.
The intended flow is:
- The parent component loads a Relay connection.
- The parent renders a MUI DataGrid from that connection.
- The parent passes the Relay connection ID (
__id) into a modal.
- The modal executes a mutation.
- Relay prepends the newly created node into the connection.
- The Relay store updates.
- The parent re-renders.
- The DataGrid immediately displays the new row.
This works perfectly until I introduce Hot Chocolate's ErrorAttribute.
Relevant implementation
Parent component
The parent owns the Relay query and Relay connection.
items
@connection(key: "ItemList_items") {
__id
edges {
node {
id
name
value
enabled
}
}
}
The Relay connection ID is passed into the modal.
<CreateItemModal
connectionId={data.items?.__id ?? ""}
/>
The DataGrid rows are derived directly from the Relay connection.
const rows = React.useMemo(() => {
return data.items?.edges?.map(({ node }) => ({
id: node?.id,
name: node?.name,
value: node?.value,
enabled: node?.enabled,
}));
}, [data.items?.edges]);
The DataGrid simply renders these rows.
<DataGridPro
rows={rows ?? []}
getRowId={(row) => row.id}
/>
There is no additional React state or manual Relay store manipulation.
Modal component
The modal receives the Relay connection ID.
interface Props {
connectionId: string;
}
When submitting the mutation, the connection ID is passed to relay.
commitMutation({
variables: {
input: {
...
},
connections: [connectionId],
},
});
Working mutation
Without ErrorAttribute, my mutation looks like this:
mutation CreateItemMutation(
$input: CreateItemInput!
$connections: [ID!]!
) {
createItem(input: $input)
@prependNode(
connections: $connections
edgeTypeName: "ItemEdge"
) {
id
name
value
enabled
}
}
Everything works exactly as expected.
Relay prepends the node into the connection, the parent component sees the updated connection, and the DataGrid immediately updates.
After introducing ErrorAttribute
I wanted to return typed domain errors using ErrorAttribute, so my mutation now returns a payload object instead.
It now looks similar to this:
mutation CreateItemMutation(
$input: CreateItemInput!
) {
createItem(input: $input) {
errors {
... on ItemAlreadyExistsError {
message
}
}
item {
id
name
value
enabled
}
}
}
The server-side error handling works perfectly.
However, because the created node is now nested under item, I can no longer use Relay's @prependNode directive.
What happens
The mutation successfully creates the record in the database.
If I refresh the page afterwards, the new record is returned by the query and displays correctly in the DataGrid.
The issue only occurs immediately after the mutation completes.
The DataGrid throws the following error:
MUI X: The data grid component requires all rows to have a unique `id` property.
Alternatively, you can use the `getRowId` prop to specify a custom id for each row.
A row was provided without id in the rows prop: {}
The DataGrid already specifies:
<DataGridPro
getRowId={(row) => row.id}
/>
When logging the newly inserted node after the mutation completes, I see:
The newly added row appears to be an empty object ({}), which causes the DataGrid error.
Refreshing the page fixes everything because the query is executed again and the server returns the correct data.
My understanding
From what I can tell, the issue isn't with MUI DataGrid.
The DataGrid is simply exposing the problem because it's rendering whatever Relay has stored.
It seems like the interaction between ErrorAttribute and Relay's declarative mutation directives is the actual issue.
Questions
- Is this expected behaviour?
- Is ErrorAttribute intended to be incompatible with Relay's declarative mutation directives like
@prependNode and @appendNode?
- Is there a recommended pattern for combining
ErrorAttribute with Relay connections?
- Is the recommended solution to always write a custom Relay updater when using ErrorAttribute?
- Is there another Hot Chocolate feature or pattern that I've overlooked which preserves compatibility with Relay's declarative mutation directives?
Additional context
I've attached both the parent component and the modal component used in this example if seeing the complete implementation is helpful.
The important part is that:
- The parent owns the Relay query and connection.
- The parent passes the connection ID (
__id) to the modal.
- The modal executes the mutation.
- The DataGrid renders directly from the Relay connection.
- There is no local React state involved.
Without ErrorAttribute, Relay updates the connection automatically and everything works as expected.
After introducing ErrorAttribute, the mutation succeeds and the record is persisted, but the Relay connection no longer appears to contain a valid node until the page is refreshed.
Any guidance would be greatly appreciated.
Thanks!
Hi everyone,
Firstly, apologies if this is the wrong repository. I'm not entirely sure whether this belongs here or on the Hot Chocolate repository.
I couldn't find an existing GitHub issue describing this scenario, although it's entirely possible that I'm missing something or that I'm using the framework incorrectly.
Environment
Hot Chocolate –
15.1.14React –
18.1.0react-relay –
16.2.0relay-runtime –
16.2.0What I'm trying to achieve
I have a page that displays a list of items using a Relay connection and a MUI DataGrid.
A user can create a new item from a modal dialog. The modal performs a Relay mutation, and I use Relay's declarative mutation directive
@prependNodeso that the newly created node is automatically inserted into the existing Relay connection.The DataGrid itself contains no local state—it simply renders whatever exists in the Relay store.
The intended flow is:
__id) into a modal.This works perfectly until I introduce Hot Chocolate's
ErrorAttribute.Relevant implementation
Parent component
The parent owns the Relay query and Relay connection.
The Relay connection ID is passed into the modal.
The DataGrid rows are derived directly from the Relay connection.
The DataGrid simply renders these rows.
There is no additional React state or manual Relay store manipulation.
Modal component
The modal receives the Relay connection ID.
When submitting the mutation, the connection ID is passed to relay.
Working mutation
Without
ErrorAttribute, my mutation looks like this:Everything works exactly as expected.
Relay prepends the node into the connection, the parent component sees the updated connection, and the DataGrid immediately updates.
After introducing
ErrorAttributeI wanted to return typed domain errors using
ErrorAttribute, so my mutation now returns a payload object instead.It now looks similar to this:
The server-side error handling works perfectly.
However, because the created node is now nested under
item, I can no longer use Relay's@prependNodedirective.What happens
The mutation successfully creates the record in the database.
If I refresh the page afterwards, the new record is returned by the query and displays correctly in the DataGrid.
The issue only occurs immediately after the mutation completes.
The DataGrid throws the following error:
The DataGrid already specifies:
When logging the newly inserted node after the mutation completes, I see:
The newly added row appears to be an empty object
({}), which causes the DataGrid error.Refreshing the page fixes everything because the query is executed again and the server returns the correct data.
My understanding
From what I can tell, the issue isn't with MUI DataGrid.
The DataGrid is simply exposing the problem because it's rendering whatever Relay has stored.
It seems like the interaction between ErrorAttribute and Relay's declarative mutation directives is the actual issue.
Questions
@prependNodeand@appendNode?ErrorAttributewith Relay connections?Additional context
I've attached both the parent component and the modal component used in this example if seeing the complete implementation is helpful.
The important part is that:
__id) to the modal.Without
ErrorAttribute, Relay updates the connection automatically and everything works as expected.After introducing
ErrorAttribute, the mutation succeeds and the record is persisted, but the Relay connection no longer appears to contain a valid node until the page is refreshed.Any guidance would be greatly appreciated.
Thanks!