ruby-grape/grape · error · ArgumentError
type #{type} should support coercion via `[]`
Error message
type #{type} should support coercion via `[]` What it means
When Grape maps a `params type:` declaration onto dry-types for coercion, it first checks a fixed MAPPING (Boolean, BigDecimal, Numeric, TrueClass, FalseClass, String) and then tries to find a constant with the same name under Dry::Types::Params (e.g. Params::Integer, Params::Date). If no such dry-type exists, Grape falls back to using the type itself for coercion, which requires the class to respond to `[]` the way Array, Hash, and Set do. When the type neither matches a dry-type constant nor responds to `[]`, Grape raises this ArgumentError at endpoint-definition time.
Source
Thrown at lib/grape/dry_types.rb:51
TrueClass => DryTypes::Params::Bool.constrained(eql: true),
FalseClass => DryTypes::Params::Bool.constrained(eql: false),
String => DryTypes::Coercible::String
}.freeze
def initialize
super
@cache = Hash.new do |h, params_type|
h[params_type] = MAPPING.fetch(params_type) do
DryTypes.wrapped_dry_types_const_get(DryTypes::Params, params_type)
end
end
end
end
def self.wrapped_dry_types_const_get(dry_type, type)
dry_type.const_get(type.name, false)
rescue NameError
raise ArgumentError, "type #{type} should support coercion via `[]`" unless type.respond_to?(:[])
end
end
end
View on GitHub (pinned to 22d7975629)
Solutions
- Use a built-in primitive that dry-types supports (String, Integer, BigDecimal, Date, Time, etc.) or one of Grape's special types (Grape::API::Boolean, Numeric).
- For custom types, give the class a `self.[]` class method (like Array/Hash/Set) so Grape can coerce with it, or implement the custom-type contract (`parse`/`parsed?`).
- Pass an explicit dry-type object instead of a class, e.g. `requires :x, type: Dry.Types(:params)[:symbol]` or a Dry::Types::Params constant.
- If the type should exist (e.g. Params::Symbol), upgrade dry-types to a version that defines it.
Example fix
# before params do requires :data, type: MyCustomValueObject # raises ArgumentError end # after params do requires :data, type: String end # or make the custom type coercible class MyCustomValueObject def self.[](raw) = parse(raw) def self.parse(raw) = new(raw) end
Defensive patterns
Strategy: type-guard
Validate before calling
SUPPORTED = { Grape::API::Boolean, BigDecimal, Numeric, TrueClass, FalseClass, String, Integer, Float, Date, Time, DateTime, Array, Hash, Set }.freeze
def coercible?(type)
SUPPORTED.include?(type) || type.respond_to?(:[]) || type.is_a?(Dry::Types::Type)
end
coercible?(MyCustomValueObject) or raise "#{MyCustomValueObject} cannot coerce params" Type guard
def grape_coercible_type?(type) return true if type.respond_to?(:[]) return true if type.is_a?(Dry::Types::Type) Dry::Types::Params.const_defined?(type.name.to_s, false) rescue NameError false end
Prevention
- Restrict `type:` declarations to built-in primitives, Grape special types, or dry-type objects.
- Cover param definitions with a boot-time smoke spec that mounts every endpoint so definition-time ArgumentErrors fail CI, not production.
- For custom types, implement `self.[]` (or `parse`/`parsed?`) and unit-test it before referencing it in params.
When it happens
Trigger: Declaring `params { requires :data, type: SomeCustomClass }` where SomeCustomClass is an application class with no class-level `[]` method. Passing `type: Symbol` or another primitive that the installed dry-types version does not expose under Dry::Types::Params. Passing a Module (e.g. `type: SomeNamespace`) instead of a class, which can never be const_get-ed on Dry::Types::Params.
Common situations: Upgrading grape or dry-types so a previously coerced type (e.g. Symbol on older dry-types) no longer has a Params constant. Using app-specific value objects as parameter types without implementing Grape's custom-type contract. Copying `type:` values from another codebase where a custom type was registered.
Related errors
- Unknown type: #{type}
- group type must be Array, Hash, JSON or Array[JSON]
- group type must be Array, Hash, JSON or Array[JSON]
- must supply type for coerce_with
- coerce_with disallowed for type: JSON
AI-assisted analysis of ruby-grape/grape@22d7975629 (2026-08-21).
Data as JSON: /api/errors/e7fa4d02c6b422b0.
Report an issue: GitHub.