activerecord-hackery/ransack · error · ArgumentError
Invalid argument (#{args.class}) supplied to attributes=
Error message
Invalid argument (#{args.class}) supplied to attributes= What it means
Nodes::Condition#attributes= (aliased a=) accepts only an Array of attribute names or a Rails-style Hash of indexed attribute descriptors ({'0' => {name: ..., ransacker_args: ...}}). Any other class — a bare String like 'name_cont', a Symbol, or a scalar — raises this ArgumentError. It is reached when building conditions programmatically or from hand-shaped params.
Source
Thrown at lib/ransack/nodes/condition.rb:92
end
def attributes
@attributes ||= []
end
alias :a :attributes
def attributes=(args)
case args
when Array
args.each do |name|
build_attribute(name)
end
when Hash
args.each do |index, attrs|
build_attribute(attrs[:name], attrs[:ransacker_args])
end
else
raise ArgumentError,
"Invalid argument (#{args.class}) supplied to attributes="
end
end
alias :a= :attributes=
def values
@values ||= []
end
alias :v :values
def values=(args)
case args
when Array
args.each do |val|
val = Value.new(@context, val)
self.values << val
end
when HashView on GitHub (pinned to e82f6bab39)
Solutions
- Wrap single attribute names in an array: condition.a = ['name_eq']
- When building via params, use the indexed hash form Rails produces: q = { c: { '0' => { a: ['name_eq'], v: ['Alice'] } } }
- Prefer the top-level attribute_key API (Person.ransack(name_eq: 'Alice')) which handles wrapping for you
Example fix
# before condition = search.build_condition condition.attributes = 'name_eq' # => ArgumentError: Invalid argument (String) supplied to attributes= # after condition.attributes = ['name_eq']
Defensive patterns
Strategy: validation
Validate before calling
attrs = Array(attrs) unless attrs.is_a?(Hash) condition.attributes = attrs # Array or indexed Hash pass, everything else is rejected
Type guard
def valid_attributes_arg?(arg) arg.is_a?(Array) || arg.is_a?(Hash) end
Prevention
- Always wrap attribute names in arrays when setting condition.a= programmatically
- Prefer Model.ransack(attr_pred => value) over hand-assembled nodes
- When importing params from JSON, normalize to the indexed {'0' => {...}} shape Rails produces
When it happens
Trigger: condition.attributes = 'name_eq' (String); condition.a = :name (Symbol); search.build(c: { a: 'name_eq' }) producing a string on a=; manually invoking Condition#build with a: 'body_cont' instead of a: ['body_cont'].
Common situations: Hand-building condition nodes in service objects or specs and forgetting the array wrapper; feeding partially-stringified params (q[c][a]=name_eq) that skip the Rails nested-hash indexing into a strict build path.
Related errors
- Invalid argument (#{args.class}) supplied to values=
- Invalid argument (#{groupings.class}) supplied to groupings=
- #{type} cannot be converted to an ARel join type
- #{value} cannot be converted to a Class
- Don't know what context to use for #{object}
AI-assisted analysis of activerecord-hackery/ransack@e82f6bab39 (2026-08-21).
Data as JSON: /api/errors/db6cf8fdca62b60c.
Report an issue: GitHub.