activerecord-hackery/ransack · error · InvalidSearchError
Invalid argument (#{args.class}) supplied to sorts=
Error message
Invalid argument (#{args.class}) supplied to sorts= What it means
Search#sorts= (aliased s=) accepts an Array of sort descriptors ('name asc', Sort nodes, or hashes), an indexed Hash of sort attribute hashes, or a single String like 'created_at desc'. Any other class — Integer, Symbol, or an arbitrary object — raises InvalidSearchError, because a sort cannot be extracted from it. It fires when q[s] arrives in an unexpected form or sorts are assigned programmatically.
Source
Thrown at lib/ransack/search.rb:82
case args
when Array
args.each do |sort|
if sort.kind_of? Hash
sort = Nodes::Sort.new(@context).build(sort)
else
sort = Nodes::Sort.extract(@context, sort)
end
self.sorts << sort if sort
end
when Hash
args.each do |index, attrs|
sort = Nodes::Sort.new(@context).build(attrs)
self.sorts << sort
end
when String
self.sorts = [args]
else
raise InvalidSearchError,
"Invalid argument (#{args.class}) supplied to sorts="
end
end
alias :s= :sorts=
def sorts
@sorts
end
alias :s :sorts
def build_sort(opts = {})
new_sort(opts).tap do |sort|
self.sorts << sort
end
end
def new_sort(opts = {})
Nodes::Sort.new(@context).build(opts)View on GitHub (pinned to e82f6bab39)
Solutions
- Pass sorts as strings: search.sorts = 'created_at desc' or ['name asc', 'created_at desc']
- Convert untrusted values first: search.sorts = params[:q][:s].to_s.split(',') if it's a single field
- Whitelist user-supplied sort columns before assignment: search.sorts = ["#{permitted_column} #{dir}"]
Example fix
# before search.sorts = :name # => Ransack::InvalidSearchError: Invalid argument (Symbol) supplied to sorts= # after search.sorts = 'name asc' # or search.sorts = ['name asc', 'created_at desc']
Defensive patterns
Strategy: validation
Validate before calling
raw = params[:q][:s] search.sorts = case raw when String, Array, Hash then raw else raw.to_s.presence # coerce scalars to string, nil/blank is skipped by sorts end
Type guard
def sortable_arg?(arg) arg.is_a?(String) || arg.is_a?(Array) || arg.is_a?(Hash) end
Try / catch
begin
search.sorts = sort_input
rescue Ransack::InvalidSearchError => e
Rails.logger.info("Ignoring bad sort input #{sort_input.inspect}: #{e.message}")
search.sorts = 'created_at desc'
end Prevention
- Always submit q[s] as strings ('name asc'); convert symbols/JSON values with to_s before assignment
- Whitelist sort column names from user input before building the sorts value
- In APIs, document and validate the sort parameter shape (string or array of strings) at the boundary
When it happens
Trigger: q[s]=123 submitted via a tampered URL to a ransack! search; search.sorts = :name (Symbol) in code; params like q[s][]= via a form control that submits a non-string; JSON payloads where the sort value is an integer or null object.
Common situations: Hand-edited or fuzzed query strings; programmatic sort assignment after refactoring from strings to symbols; API layers forwarding typed JSON into Ransack params unconverted.
Related errors
- No valid predicate for #{key}
- Invalid search term #{key}
- sort_direction must be called inside a search FormBuilder!
- #{type} cannot be converted to an ARel join type
- #{value} cannot be converted to a Class
AI-assisted analysis of activerecord-hackery/ransack@e82f6bab39 (2026-08-21).
Data as JSON: /api/errors/e26af003c4731f5a.
Report an issue: GitHub.