ruby-grape/grape · error · Grape::Exceptions::UnknownValidator
unknown validator: %{validator_type}
Error message
unknown validator: %{validator_type} What it means
Every option in a `params` block that looks like a validator (allow_blank, values, regexp, default, length, same_as, except_values, and the *_of group validators) is resolved through Grape::Validations' registry by short name. When an option key matches no registered validator - a typo or an unregistered custom validator - Grape raises Grape::Exceptions::UnknownValidator while building the endpoint.
Source
Thrown at lib/grape/validations.rb:10
# frozen_string_literal: true
module Grape
module Validations
extend Grape::Util::Registry
module_function
def require_validator(short_name)
raise Grape::Exceptions::UnknownValidator, short_name unless registry.key?(short_name)
registry[short_name]
end
def build_short_name(klass)
return if klass.name.blank?
klass.name.demodulize.underscore.delete_suffix('_validator')
end
end
end
View on GitHub (pinned to 22d7975629)
Solutions
- Fix the typo to a real validator option: allow_blank, values, regexp, default, length, same_as, etc.
- Register custom validators: define a class ending in Validator (e.g. MyCheckValidator < Grape::Validations::Validators::Base) and call `Grape::Validations.register_validator(MyCheckValidator)` (Rails autoloaders may require eager_load in dev).
- If the option is metadata for your own code, rename it so it does not collide with validator resolution.
Example fix
# before
requires :email, type: String, presense: true # raises UnknownValidator: presense
# after
requires :email, type: String, allow_blank: false
# custom
class MyCheckValidator < Grape::Validations::Validators::Base
def validate_param!(attr, params)
@api.error!("#{attr} failed check", 400) unless params[attr].match?(/ok/)
end
end
Grape::Validations.register_validator(MyCheckValidator)
requires :x, my_check: true Defensive patterns
Strategy: validation
Validate before calling
KNOWN_VALIDATORS = %w[allow_blank values regexp default length same_as except_values as
at_least_one_of exactly_one_of all_or_none_of mutually_exclusive].freeze
unknown = declared_opts.keys.map(&:to_s) - KNOWN_VALIDATORS - %w[type coerce]
raise ArgumentError, "unregistered validators: #{unknown.join(', ')}" if unknown.any? Type guard
def registered_validator?(name) = Grape::Validations.require_validator(name) && true rescue Grape::Exceptions::UnknownValidator false end
Try / catch
begin Grape::Validations.require_validator(:my_check) rescue Grape::Exceptions::UnknownValidator Grape::Validations.register_validator(MyCheckValidator) # lazy registration before params load end
Prevention
- Check option spelling against the validators list (allow_blank, values, regexp, default, length, same_as...).
- Register custom validators in an initializer that loads before API classes; with Rails autoloading use `Rails.application.config.to_prepare`.
- Boot specs per endpoint surface UnknownValidator at CI time.
When it happens
Trigger: `requires :email, presense: true` (typo for allow_blank/presence semantics). `optional :x, my_check: true` where MyCheckValidator was never registered. Using a validator from a gem or initializer that is not loaded in the current environment.
Common situations: Misspelled validation options. Custom validators defined in lib/ that load after the API class. Disabling an initializer in test/development that registers validators. Copying params from a project with extra registered validators.
Related errors
- type #{type} should support coercion via `[]`
- #declared is not available prior to parameter validation
- group type is required
- group type must be Array, Hash, JSON or Array[JSON]
- Either contract or block must be provided
AI-assisted analysis of ruby-grape/grape@22d7975629 (2026-08-21).
Data as JSON: /api/errors/1c500207820119e5.
Report an issue: GitHub.