You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Configure the GraphQL server with the persisted operation pipeline enabled, like this:
var graphql = services
.AddSha256DocumentHashProvider()
.AddGraphQLServer()
.AddQueryType<Query>()
.AddMutationType<Mutation>()
.UsePersistedOperationPipeline()
.AddFileSystemOperationDocumentStorage("./persisted_operations");
Define a mutation that deletes a record and checks if it exists first. For example:
public class Mutation
{
public async Task<string> DeleteRecord(int id, [Service] IRecordService service)
{
var record = await service.GetRecordAsync(id);
if (record == null)
return "NotFound";
await service.DeleteRecordAsync(id);
return "Success";
}
}
Ensure a record exists in your data store (e.g., id: 1).
Execute the mutation with a persisted operation, passing an existing record ID (e.g., id: 1).
What is expected?
When the mutation runs:
It should execute once.
What is actually happening?
When the mutation runs with .UsePersistedOperationPipeline() and .AddFileSystemOperationDocumentStorage("./persisted_operations") enabled:
The mutation executes twice.
The first execution deletes the record successfully.
Instead of returning "Success", it runs again, finds the record missing, and returns "NotFound".
Relevant log output
Additional context
Behavior without persisted operations: This issue does not occur if .UsePersistedOperationPipeline() and .AddFileSystemOperationDocumentStorage("./persisted_operations") are removed from the configuration. In that case, the mutation executes once and returns "Success" as expected.
Example scenario: Imagine a mutation designed to delete a record. It first checks if the record exists. If it does, the record is deleted, and a success message ("Success") should be returned. If it doesn’t exist, it returns "NotFound". With the persisted operation pipeline enabled, the mutation deletes the record on the first run but doesn’t return "Success". Instead, it executes again, sees the record is gone, and returns "NotFound". This double execution is unexpected and breaks the intended logic.
Environment:
Dotnet version 9
HotChocolate version: v15 (latest release).
The text was updated successfully, but these errors were encountered:
pscyfer
changed the title
Mutations Execute Twice When Using Persisted Operation Pipeline in HotChocolate v15
Mutations Execute Twice When Using Persisted Operation Pipeline in v15
Feb 27, 2025
Product
Hot Chocolate
Version
15.0.3
Steps to reproduce
Configure the GraphQL server with the persisted operation pipeline enabled, like this:
Define a mutation that deletes a record and checks if it exists first. For example:
Ensure a record exists in your data store (e.g., id: 1).
Execute the mutation with a persisted operation, passing an existing record ID (e.g., id: 1).
What is expected?
When the mutation runs:
It should execute once.
What is actually happening?
When the mutation runs with .UsePersistedOperationPipeline() and .AddFileSystemOperationDocumentStorage("./persisted_operations") enabled:
The mutation executes twice.
The first execution deletes the record successfully.
Instead of returning "Success", it runs again, finds the record missing, and returns "NotFound".
Relevant log output
Additional context
Behavior without persisted operations: This issue does not occur if .UsePersistedOperationPipeline() and .AddFileSystemOperationDocumentStorage("./persisted_operations") are removed from the configuration. In that case, the mutation executes once and returns "Success" as expected.
Example scenario: Imagine a mutation designed to delete a record. It first checks if the record exists. If it does, the record is deleted, and a success message ("Success") should be returned. If it doesn’t exist, it returns "NotFound". With the persisted operation pipeline enabled, the mutation deletes the record on the first run but doesn’t return "Success". Instead, it executes again, sees the record is gone, and returns "NotFound". This double execution is unexpected and breaks the intended logic.
Environment:
Dotnet version 9
HotChocolate version: v15 (latest release).
The text was updated successfully, but these errors were encountered: