Graphql-ruby: Type mismatch on variable $pageSize and argument pageSize (Int / Int)

Created on 27 Feb 2020  路  11Comments  路  Source: rmosolgo/graphql-ruby

With the latest version , when I run queries like

    query($contentAreaSlug: String!,
          $contentTypes: [ContentTypes!],
          $page: Int,
          $pageSize: Int,
          $sortBy: String,
          $direction: SortDirection,
          $publishStatuses: [PublishStatuses!],
          $internalStatuses: [InternalStatuses],
          $externalTypes: [ExternalTypes],
          $keyword: String,
          $publishDateStart: ISO8601DateTime,
          $publishDateEnd: ISO8601DateTime,
          $contributorRoleSlug: String,
          $contributorProfileIds: [String]) {
            contentList(contentAreaSlug: $contentAreaSlug,
                        contentTypes: $contentTypes,
                        page: $page,
                        pageSize: $pageSize,
                        sortBy: $sortBy,
                        direction: $direction,
                        publishStatuses: $publishStatuses,
                        internalStatuses: $internalStatuses,
                        externalTypes: $externalTypes,
                        keyword: $keyword,
                        publishDateStart: $publishDateStart,
                        publishDateEnd: $publishDateEnd,
                        contributorRoleSlug: $contributorRoleSlug,
                        contributorProfileIds: $contributorProfileIds) {
                          totalPages
                          currentPage
                          totalItems
                          previousPage
                          nextPage
                          items {
                            title
                            canonicalSlug
                            contentAreaSlug
                            resourceType
                            publishDate
                            updatedAt
                            createdAt
                            internalStatus
                            publishStatus
                            userId
                            externalType
                            primaryVisuals {
                              thumbnail {
                                slug
                                preferredAspectRatio {
                                  instances {
                                    url
                                  }
                                }
                                aspectRatios {
                                  square {
                                    slug
                                    instances {
                                      url
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
            }

I get errors like

#<StandardError: [{"message"=>"Type mismatch on variable $page and argument page (Int / Int)", "locations"=>[{"line"=>17, "column"=>25}], "path"=>["query GraphQL__Client__OperationDefinition_70213633881320", "contentList", "page"], "extensions"=>{"code"=>"variableMismatch", "variableName"=>"page", "typeName"=>"Int", "argumentName"=>"page", "errorMessage"=>"Type mismatch"}}, {"message"=>"Type mismatch on variable $pageSize and argument pageSize (Int / Int)", "locations"=>[{"line"=>18, "column"=>25}], "path"=>["query GraphQL__Client__OperationDefinition_70213633881320", "contentList", "pageSize"], "extensions"=>{"code"=>"variableMismatch", "variableName"=>"pageSize", "typeName"=>"Int", "argumentName"=>"pageSize", "errorMessage"=>"Type mismatch"}}]>

Not sure where if I've goofed up my types or if this is a bug.

Most helpful comment

It was trickier than I thought to catch this programatically during schema boot 馃槄 Hopefully people who run into it will find this issue.

All 11 comments

If I use pry to bind in at lib/graphql/static_validation/rules/variable_usages_are_allowed.rb:76 if var_inner_type != arg_inner_type I get GraphQL::Types::Int for var_inner_type and Int for arg_inner_type

adding the following to my schema works around the issue in my test suite but I'm clear as to why

    def self.type_from_ast(*args)
      type = super
      type == GraphQL::Types::Int ? type.to_graphql : type
    end

馃檧 Somehow, it's got the new-style Types::Int object in one case, but the legacy INT_TYPE object in another case.

There's definitely a bug that it _should_ have caught this during initalization.

Are you using GraphQL::Execution::Interpreter? Could you share the definition of your argument :page_size?

Here's the schema root:

# frozen_string_literal: true

module ApmGraphqlApi
  class ApmContentSchema < GraphQL::Schema
    query(ApmGraphqlApi::Types::Query)
    use GraphQL::Execution::Interpreter
    use GraphQL::Analysis::AST

    use GraphQL::Batch
    use(GraphQL::Tracing::NewRelicTracing) if Object.const_defined?('NewRelic')

    def self.type_from_ast(*args)
      type = super
      type == GraphQL::Types::Int ? type.to_graphql : type
    end
  end
end

and the definition:

# frozen_string_literal: true

module ApmGraphqlApi
  module Types
    class ContentListArgumentsExtension < GraphQL::Schema::FieldExtension
      def apply
        field.argument :content_area_slug, String, required: true
        field.argument :publish_statuses, [Types::PublishStatuses], required: false, default_value: %w[published]
        field.argument :page, GraphQL::INT_TYPE, required: false
        field.argument :page_size, GraphQL::INT_TYPE, required: false, default_value: ApmGraphqlApi::Defaults::PAGE_SIZE
        field.argument :sort_by, String, required: false, default_value: 'publish_date'
        # TODO: get sort direction "sorted" between the deprecated content lists (episode_list etc)
        # where sort_direction is a String and the newer content_list where it is an ENUM
        field.argument :publish_date_start, GraphQL::Types::ISO8601DateTime, required: false
        field.argument :publish_date_end, GraphQL::Types::ISO8601DateTime, required: false
      end
    end
  end
end

Which has the old types. I missed it because I wasn't looking in the extension! I can leave this open if you think there is some validation needed. Meanwhile I'm off to see if setting those to plain ol' Ints get me back on track.

Thanks for the details here! Yes, let's keep it open, I'll look for some way to avoid this in the future.

That did the trick for me. Thanks again for the quick response and for building this very useful beast of a library.

Back when I first started using graphql gem, I used GraphQL::ID_TYPE because that's the only "id" type that worked. Perhaps it would be good to have deprecation warnings when old types are used? Because, from an outsider's perspective, all of these types seem the same, just different name.

I just tried switching to ID, but that doesn't work in mutations:
uninitialized constant Mutations::Arguments::SubmittableArguments::ID

If the above mutation doesn't work, I don't think that the mutations in documentation would work either: https://graphql-ruby.org/mutations/mutation_classes

What's the constant that I can use that should work? Thanks!

ID is available inside scopes where this module is included:

https://github.com/rmosolgo/graphql-ruby/blob/7ecaeec937151c8a4d6d1457a98ec2d50c8ef016/lib/graphql/schema/member/graphql_type_names.rb#L14-L18

That module is included in GraphQL-Ruby's schema classes, but it looks like you might be defining an argument outside that scope. Is that right?

You could also use "ID" (string) or GraphQL::Types::ID:

https://github.com/rmosolgo/graphql-ruby/blob/7ecaeec937151c8a4d6d1457a98ec2d50c8ef016/lib/graphql/types/id.rb#L4

Sorry about the confusion! (It's because GraphQL-Ruby's types _used to_ override def ==(other), but they don't anymore -- so some checks are failing. But obviously it needs to be improved to cover some cases!)

Ahhh I see!

Here's how I define the "id" type, it's a bit lengthy:

module Mutations
  class EventCreate < Mutations::BaseMutation
    # arguments
    class EventCreateInput < Types::BaseInputObject
      include Arguments::SubmittableArguments
      include Arguments::EventArguments
    end
    argument :input, EventCreateInput, required: true

    # field
    field :event, Types::EventType, null: true

    def resolve(input:)
      # ...
    end
  end
end
module Mutations
  module Arguments::SubmittableArguments
    extend ActiveSupport::Concern

    included do
      argument :community_id, GraphQL::ID_TYPE, required: false, loads: Types::CommunityType
    end
  end
end

So that fails if I change it to:

argument :community_id, ID, required: false, loads: Types::CommunityType

I'll try with GrahpQL::Types::ID. Perhaps it would be good to always use the full name GraphQL::Types::ID, as ID is not really that specific and/or it might be out of "namespace scope", like what happened to me.

EDIT: GrahpQL::Types::ID works as expected! :) Thanks!

It was trickier than I thought to catch this programatically during schema boot 馃槄 Hopefully people who run into it will find this issue.

I'm getting this issue still. @etherbob 's fix works for me. If you need anything from me, let me know. You can view relevant information on my Stack Overflow post here.

Was this page helpful?
0 / 5 - 0 ratings