-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Describe the bug
getting an error: GraphQL::Schema::Directive::InvalidArgumentError: @documentation.options on <my_field> is invalid ([{:key=>"1", :value=>"1"}]): Expected value to not be null
I have a documentation
Directive with a single argument: argument :options, [DirectiveOption, null: true], required: false
with a custom input object DirectiveOption
defined as:
class DirectiveOption < GraphQL::Schema::InputObject
argument :key, String, required: true
argument :value, String, required: true
end
in another module, I attach this directive to relevant Schema objects by: directive(Directives::SpectaQL, options: directive_options)
where directive_options
is an array of key-value pairs like: [{ :key => '1', :value =>'1' }, { :key => '2', :value => '2' }]
. I attempted a fix by using string keys instead of symbol keys: [{ 'key' => '1', 'value' =>'1' }, { 'key' => '2', 'value' => '2' }]
but still got the same error. So far the only workaround (not ideal) is not using a custom input object and using a scalar type (e.g. string) instead.
Versions
graphql
version: 2.5.11
rails
(or other framework):
other applicable versions (graphql-batch
, etc)
GraphQL schema
Include relevant types and fields (in Ruby is best, in GraphQL IDL is ok). Any custom extensions, etc?
# frozen_string_literal: true
module Directives
class SpectaQL < GraphQL::Schema::Directive
graphql_name 'documentation'
class DirectiveOption < GraphQL::Schema::InputObject
graphql_name 'DocumentationOption'
argument :key, String, required: true
argument :value, String, required: true
end
argument :options, [DirectiveOption, null: true], required: false
locations QUERY, MUTATION, SUBSCRIPTION, FIELD,
FRAGMENT_DEFINITION, FRAGMENT_SPREAD, INLINE_FRAGMENT, VARIABLE_DEFINITION,
SCHEMA, SCALAR, OBJECT, FIELD_DEFINITION, ARGUMENT_DEFINITION,
INTERFACE, UNION, ENUM, ENUM_VALUE, INPUT_OBJECT, INPUT_FIELD_DEFINITION
end
end
# frozen_string_literal: true
module HasSpectaQLDirective
attr_reader :spectaql
def spectaql=(options)
directive_options = options.map do |k, v|
case k
when :1
{ key: '1', value: v.to_s }
when :2
{ key: '2', value: v.to_s }
when :3
{ key: '3', value: v.to_s }
else
raise ArgumentError.new "Invalid key for spectaql= :: #{k}"
end
end
if directive_options.present?
directive(Directives::SpectaQL, options: directive_options)
end
end
end
GraphQL query
N/A
Steps to reproduce
Steps to reproduce the behavior
- build schema with command
graphql:schema:idl
Expected behavior
- schema builds successfully with directive attached
Actual behavior
getting an error: GraphQL::Schema::Directive::InvalidArgumentError: @documentation.options on <my_field> is invalid ([{:key=>"1", :value=>"1"}]): Expected value to not be null
. see full backtrace here:
Click to view exception backtrace
GraphQL::Schema::Directive::InvalidArgumentError: @documentation.options on <my_field> is invalid ([{:key=>"1", :value=>"1"}]): Expected value to not be null
/bundle/ruby/3.0.0/gems/graphql-2.5.11/lib/graphql/schema/directive.rb:147:in `block in initialize'
/bundle/ruby/3.0.0/gems/graphql-2.5.11/lib/graphql/schema/directive.rb:131:in `each'
/bundle/ruby/3.0.0/gems/graphql-2.5.11/lib/graphql/schema/directive.rb:131:in `initialize'
/bundle/ruby/3.0.0/gems/graphql-2.5.11/lib/graphql/schema/member/has_directives.rb:43:in `new'
/bundle/ruby/3.0.0/gems/graphql-2.5.11/lib/graphql/schema/member/has_directives.rb:43:in `add_directive'
/bundle/ruby/3.0.0/gems/graphql-2.5.11/lib/graphql/schema/member/has_directives.rb:24:in `directive'
/app/graphql/concerns/has_spectaql_directive.rb:31:in `spectaql='
/app/graphql/types/base_field.rb:143:in `initialize'
/bundle/ruby/3.0.0/gems/graphql-2.5.11/lib/graphql/schema/field.rb:155:in `new'
/bundle/ruby/3.0.0/gems/graphql-2.5.11/lib/graphql/schema/field.rb:155:in `from_options'
/bundle/ruby/3.0.0/gems/graphql-2.5.11/lib/graphql/schema/member/has_fields.rb:12:in `field'
/bundle/ruby/3.0.0/gems/activesupport-6.1.7.10/lib/active_support/option_merger.rb:34:in `invoke_method'
/bundle/ruby/3.0.0/gems/activesupport-6.1.7.10/lib/active_support/option_merger.rb:28:in `method_missing'
/app/graphql/types/delivery_stats_record.rb:6:in `block in <class:DeliveryStatsRecord>'
/bundle/ruby/3.0.0/gems/activesupport-6.1.7.10/lib/active_support/core_ext/object/with_options.rb:80:in `instance_eval'
/bundle/ruby/3.0.0/gems/activesupport-6.1.7.10/lib/active_support/core_ext/object/with_options.rb:80:in `with_options'
/app/graphql/types/delivery_stats_record.rb:5:in `<class:DeliveryStatsRecord>'
/app/graphql/types/delivery_stats_record.rb:2:in `<module:Types>'
/app/graphql/types/delivery_stats_record.rb:1:in `<main>'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/zeitwerk-2.6.18/lib/zeitwerk/kernel.rb:26:in `require'
/app/graphql/types/delivery_stats.rb:6:in `block in <class:DeliveryStats>'
/bundle/ruby/3.0.0/gems/activesupport-6.1.7.10/lib/active_support/core_ext/object/with_options.rb:80:in `instance_eval'
/bundle/ruby/3.0.0/gems/activesupport-6.1.7.10/lib/active_support/core_ext/object/with_options.rb:80:in `with_options'
/app/graphql/types/delivery_stats.rb:5:in `<class:DeliveryStats>'
/app/graphql/types/delivery_stats.rb:2:in `<module:Types>'
/app/graphql/types/delivery_stats.rb:1:in `<main>'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/zeitwerk-2.6.18/lib/zeitwerk/kernel.rb:26:in `require'
/app/graphql/types/conversion_pixel.rb:17:in `block (2 levels) in <class:ConversionPixel>'
/bundle/ruby/3.0.0/gems/activesupport-6.1.7.10/lib/active_support/core_ext/object/with_options.rb:80:in `instance_eval'
/bundle/ruby/3.0.0/gems/activesupport-6.1.7.10/lib/active_support/core_ext/object/with_options.rb:80:in `with_options'
/app/graphql/types/conversion_pixel.rb:14:in `block in <class:ConversionPixel>'
/bundle/ruby/3.0.0/gems/activesupport-6.1.7.10/lib/active_support/core_ext/object/with_options.rb:80:in `instance_eval'
/bundle/ruby/3.0.0/gems/activesupport-6.1.7.10/lib/active_support/core_ext/object/with_options.rb:80:in `with_options'
/app/graphql/types/conversion_pixel.rb:13:in `<class:ConversionPixel>'
/app/graphql/types/conversion_pixel.rb:4:in `<module:Types>'
/app/graphql/types/conversion_pixel.rb:3:in `<main>'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/zeitwerk-2.6.18/lib/zeitwerk/kernel.rb:26:in `require'
/app/graphql/types/interfaces/pixel.rb:219:in `<module:Pixel>'
/app/graphql/types/interfaces/pixel.rb:4:in `<module:Interfaces>'
/app/graphql/types/interfaces/pixel.rb:3:in `<main>'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/zeitwerk-2.6.18/lib/zeitwerk/kernel.rb:26:in `require'
/app/graphql/types/account.rb:17:in `<class:Account>'
/app/graphql/types/account.rb:4:in `<module:Types>'
/app/graphql/types/account.rb:3:in `<main>'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/zeitwerk-2.6.18/lib/zeitwerk/kernel.rb:26:in `require'
/app/graphql/mutations/update_account.rb:15:in `<class:UpdateAccount>'
/app/graphql/mutations/update_account.rb:2:in `<module:Mutations>'
/app/graphql/mutations/update_account.rb:1:in `<main>'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'`
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'`
/bundle/ruby/3.0.0/gems/zeitwerk-2.6.18/lib/zeitwerk/kernel.rb:26:in `require'
/app/graphql/types/mutation_type.rb:6:in `<class:MutationType>'
/app/graphql/types/mutation_type.rb:2:in `<module:Types>'
/app/graphql/types/mutation_type.rb:1:in `<main>'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/zeitwerk-2.6.18/lib/zeitwerk/kernel.rb:26:in `require'
/app/graphql/schema.rb:4:in `<class:SASchema>'
/app/graphql/schema.rb:3:in `<main>'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/zeitwerk-2.6.18/lib/zeitwerk/kernel.rb:26:in `require'
/app/graphql/public_schema.rb:3:in `<main>'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/bundle/ruby/3.0.0/gems/zeitwerk-2.6.18/lib/zeitwerk/kernel.rb:26:in `require'
/lib/tasks/graphql.rake:6:in `block in <main>'
/bundle/ruby/3.0.0/gems/graphql-2.5.11/lib/graphql/rake_task.rb:101:in `write_outfile'
/bundle/ruby/3.0.0/gems/graphql-2.5.11/lib/graphql/rake_task.rb:147:in `block (3 levels) in define_task'
/bundle/ruby/3.0.0/gems/rake-13.2.1/exe/rake:27:in `<top (required)>'
Tasks: TOP => graphql:schema:idl
(See full trace by running task with --trace)
Additional context
error occurred during graphql-ruby gem upgrade from 2.2.17 -> 2.5.x. Through trial and error confirmed that the last working version is v2.5.7. So in v2.5.8 this bug was introduced. relevant PR found: #5377