ruby-grape/grape · error · ArgumentError
both :with option and block cannot be passed
Error message
both :with option and block cannot be passed
What it means
`rescue_from` lets you specify a handler either as an inline block or via the `with:` option (a method name or Proc), but not both - Grape would not know which one wins. `extract_handler` raises 'both :with option and block cannot be passed' when a block is given and `with:` is non-nil.
Source
Thrown at lib/grape/dsl/request_response.rb:145
# end
#
# Note that Grape will automatically go up the class ancestry to
# try to find a representing entity, so if you, for example, define
# an entity to represent `Object` then all presented objects will
# bubble up and utilize the entity provided on that `represent` call.
#
# @param model_class [Class] The model class that will be represented.
# @option options [Class] :with The entity class that will represent the model.
def represent(model_class, with:)
raise Grape::Exceptions::InvalidWithOptionForRepresent.new unless with.is_a?(Class)
inheritable_setting.add_representation(model_class, with)
end
private
def extract_handler(args, with:, block:)
raise ArgumentError, 'both :with option and block cannot be passed' if block && with
return args.pop if args.last.is_a?(Proc)
return block if block
return unless with
case with
when Proc, Symbol then with
when String then with.to_sym
else raise ArgumentError, "with: #{with.class}, expected Symbol, String or Proc"
end
end
end
end
end
View on GitHub (pinned to 22d7975629)
Solutions
- Keep the block and drop `with:`.
- Keep `with:` and delete the block, ensuring the named method or lambda is defined on the endpoint.
Example fix
# before rescue_from ArgumentError, with: :render_error do |e| error!(e.message, 400) end # raises # after - handler method only rescue_from ArgumentError, with: :render_error def render_error(e); error!(e.message, 400); end # or block only rescue_from ArgumentError do |e| error!(e.message, 400) end
Defensive patterns
Strategy: validation
Validate before calling
# House rule: either an inline block XOR with: - never both raise ArgumentError, 'pass either block or with:, not both' if handler_block && with_option
Prevention
- When extracting a handler to a method, delete the block in the same commit.
- Avoid single-line `with: ->(e){}` lambdas followed by do/end - easy to create accidentally.
- Boot specs per endpoint catch this at load time.
When it happens
Trigger: `rescue_from ArgumentError, with: :render_error do |e| ... end`. `rescue_from :all, with: ->(e) { ... } do |e| ... end` - a do/end block after a with: lambda.
Common situations: Refactoring a handler into a named method and forgetting to delete the old block. A stray multiline do/end sneaking in after a `with:` lambda. Merging two rescue_from declarations during conflict resolution.
Related errors
- with: #{with.class}, expected Symbol, String or Proc
- rescue_from #{meta_selector.inspect} does not accept additio
- Returning or throwing a Hash from a rescue handler is deprec
- Grape: rescue_from #{klass} was already registered in this s
- Grape: rescue_from #{klass} will never run — #{covered_by} w
AI-assisted analysis of ruby-grape/grape@22d7975629 (2026-08-21).
Data as JSON: /api/errors/706e7547b97deafb.
Report an issue: GitHub.