Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutations Execute Twice When Using Persisted Operation Pipeline in v15 #8076

Open
pscyfer opened this issue Feb 27, 2025 · 5 comments
Open

Comments

@pscyfer
Copy link

pscyfer commented 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:

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).

@pscyfer 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
@PascalSenn
Copy link
Member

@pscyfer any chance that you configuration method is called twice?

@pscyfer
Copy link
Author

pscyfer commented Feb 27, 2025

@PascalSenn No. by removing .UsePersistedOperationPipeline() everything works ok

@michaelstaib
Copy link
Member

Can you create a small repro that shows this behavior?

@michaelstaib
Copy link
Member

There does not have to be a database involved simply log into the console.

@michaelstaib
Copy link
Member

I wired up the server as specified and it works as expected.

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants