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_opts

View on GitHub (pinned to 22d7975629)

Solutions

  1. Remove the stale field from `except`.
  2. Add the field to the `using` hash if it should still be declared: `using: { ..., email: { type: String } }`.
  3. 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

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


AI-assisted analysis of ruby-grape/grape@22d7975629 (2026-08-21). Data as JSON: /api/errors/3d5e3c39bb684c2f. Report an issue: GitHub.