ruby-grape/grape · error · ArgumentError
required field not exist: #{field}
Error message
required field not exist: #{field} What it means
With `requires ... using: HASH, except: [...]`, Grape re-declares the using-hash fields, and in the 'none' context (:none means only the except-ed fields become required) every field listed in `except` must exist in the `using` hash. When an except entry has no entry in using, Grape cannot build a `requires` for it and raises 'required field not exist: X' at definition time.
Source
Thrown at lib/grape/validations/params_scope.rb:244
# renamed name, with the +as: ...+ semantic)
def push_renamed_param(path, new_name)
@api.inheritable_setting.add_route_renamed_param(Array(path).map(&:to_s), new_name.to_s)
end
def require_required_and_optional_fields(context, using:, except: nil)
except_fields = Array.wrap(except)
using_fields = using.keys.delete_if { |f| except_fields.include?(f) }
if context == :all
optional_fields = except_fields
required_fields = using_fields
else # context == :none
required_fields = except_fields
optional_fields = using_fields
end
required_fields.each do |field|
field_opts = using[field]
raise ArgumentError, "required field not exist: #{field}" unless field_opts
requires(field, **field_opts)
end
optional_fields.each do |field|
field_opts = using[field]
optional(field, **field_opts) if field_opts
end
end
def require_optional_fields(context, using:, except: nil)
optional_fields = using.keys
unless context == :all
except_fields = Array.wrap(except)
optional_fields.delete_if { |f| except_fields.include?(f) }
end
optional_fields.each do |field|
field_opts = using[field]
optional(field, **field_opts) if field_optsView on GitHub (pinned to 22d7975629)
Solutions
- Remove the stale field from `except`.
- Add the field to the `using` hash if it should still be declared: `using: { ..., email: { type: String } }`.
- Keep using and except in sync by deriving except from using.keys in test/setup code.
Example fix
# before
requires :filters,
using: { name: { type: String }, age: { type: Integer } },
except: [:email] # raises 'required field not exist: email'
# after
requires :filters,
using: { name: { type: String }, age: { type: Integer }, email: { type: String } },
except: [:email] Defensive patterns
Strategy: validation
Validate before calling
missing = except_fields - using_hash.keys
raise ArgumentError, "except fields missing from using: #{missing.join(', ')}" if missing.any?
requires :filters, using: using_hash, except: except_fields Prevention
- Keep using/except pairs adjacent and derived from one source (e.g. a constant keys list).
- Run `except - using.keys` checks in a spec that boots the endpoint.
- Rename fields in both places in the same commit.
When it happens
Trigger: `requires :filters, using: { name: { type: String }, age: { type: Integer } }, except: [:email]` - :email is not a key of using. Renaming fields in the using hash but not in except. Passing except as a single symbol that does not match any using key.
Common situations: Maintaining a shared using/except allow-list as params evolve. Copying an except list from another endpoint with a different using hash. Field renamed in a schema refactor.
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/3d5e3c39bb684c2f.
Report an issue: GitHub.