Skip to content

Optional<T?> produces an "Unable to convert the value of the argument..." error when used in conjunction with mutation conventions #4726

Closed

Description

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

When creating a mutation resolver that uses the new mutation conventions feature, using Optional<T?> argument types instead of the base type, results in an Unable to convert the value of the argument... error when executing the mutation.

This only occurs when the input types are automatically generated from the mutation resolver method signature and one or more of those arguments is wrapped in an Optional<> type.

When mutation conventions are disabled and a DTO is created for the input and payload types, the optional values work perfectly and no value conversion errors occur.

Steps to reproduce

  1. Enable mutation conventions for the entire project or a specific mutation resolver method.
  2. Add an Optional<T?> parameter to the method signature.

Here is a repository that demonstrates both the broken mutation conventions and the working DTOs:
https://github.com/kirkbrauer/HotChocolateMutationConventionsOptional

Relevant log output

{
  "errors": [
    {
      "message": "Unable to convert the value of the argument `description` to `System.String`. Check if the requested type is correct or register a custom type converter.",
      "locations": [
        {
          "line": 14,
          "column": 3
        }
      ],
      "path": [
        "createBookMutationConvention"
      ],
      "extensions": {
        "fieldName": "createBookMutationConvention",
        "argumentName": "description",
        "requestedType": "System.String"
      }
    }
  ]
}

Additional Context?

Here are the basic resolver implementations for both the working and broken resolvers:

public class Mutation
{
    public Book CreateBookMutationConvention(
        string title,
        Optional<string?> description)
    {
        return new Book
        {
            Id = Guid.NewGuid(),
            Title = title,
            Description = description.HasValue ? description : "No Description"
        };
    }
        
    [UseMutationConvention(Disable = true)]
    public CreateBookPayload CreateBookOld(CreateBookInput input)
    {
        return new CreateBookPayload(new Book
        {
            Id = Guid.NewGuid(),
            Title = input.Title,
            Description = input.Description.HasValue ? input.Description : "No Description"
        });
    }
}

Here are the queries that produce the error using the two types of resolvers:

# Fails with "Unable to convert the value of the argument `description` to `System.String`. Check if the requested type is correct or register a custom type converter."
mutation CreateBookMutationConventionsHasValue {
  createBookMutationConvention(input: { title: "Hello, world", description: "This is a book's description." }) {
    book {
      id
      title
      description
    }
  }
}

# Fails with "Unable to convert the value of the argument `description` to `System.String`. Check if the requested type is correct or register a custom type converter."
mutation CreateBookMutationConventionsNoValue {
  createBookMutationConvention(input: { title: "Hello, world" }) {
    book {
      id
      title
      description
    }
  }
}

# Fails with "Unable to convert the value of the argument `description` to `System.String`. Check if the requested type is correct or register a custom type converter."
mutation CreateBookMutationConventionsNull {
  createBookMutationConvention(input: { title: "Hello, world", description: null }) {
    book {
      id
      title
      description
    }
  }
}

# Works perfectly
mutation CreateBookOld {
  createBookOld(input: {  title: "Hello, world", description: "This is a book's description." }) {
    book {
      id
      title
      description
    }
  }
}

# Works perfectly
mutation CreateBookOldNoValue {
  createBookOld(input: {  title: "Hello, world" }) {
    book {
      id
      title
      description
    }
  }
}

# Works perfectly
mutation CreateBookOldNoValueNull {
  createBookOld(input: {  title: "Hello, world", description: null }) {
    book {
      id
      title
      description
    }
  }
}

Product

Hot Chocolate

Version

12.6.0, 12.7.0-preview.4

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

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions