ankane/searchkick · error · ArgumentError
Use Searchkick.search to search multiple models
Error message
Use Searchkick.search to search multiple models
What it means
Every Searchkick knn (vector) search needs a distance metric. It is resolved from knn[:distance] or from the field's entry in the model's searchkick knn: {field: {distance: ...}} settings; if neither is present the query cannot be built and Searchkick raises ArgumentError 'distance required' in set_knn.
Source
Thrown at lib/searchkick.rb:177
# convert index_name into models if possible
# this should allow for easier upgrade
if options[:index_name] && !options[:models] && Array(options[:index_name]).all? { |v| v.respond_to?(:searchkick_index) }
options[:models] = options.delete(:index_name)
end
# make Searchkick.search(models: [Product]) and Product.search equivalent
unless klass
models = Array(options[:models])
if models.size == 1
klass = models.first
options.delete(:models)
end
end
if klass
if (options[:models] && Array(options[:models]) != [klass]) || Array(options[:index_name]).any? { |v| v.respond_to?(:searchkick_index) && v != klass }
raise ArgumentError, "Use Searchkick.search to search multiple models"
end
end
options = options.merge(block: block) if block
Relation.new(klass, term, **options)
end
def self.multi_search(queries, opaque_id: nil)
return if queries.empty?
queries = queries.map { |q| q.send(:query) }
event = {
name: "Multi Search",
body: queries.flat_map { |q| [q.params.except(:body).to_json, q.body.to_json] }.map { |v| "#{v}\n" }.join
}
ActiveSupport::Notifications.instrument("multi_search.searchkick", event) do
MultiSearch.new(queries, opaque_id: opaque_id).perform
endView on GitHub (pinned to 93e901a75b)
Solutions
- Set distance in the model mapping so every query inherits it: searchkick knn: {embedding: {dimensions: 384, distance: 'cosine'}} (a reindex is needed for the mapping)
- Or pass it per query: Product.search('*', knn: {field: :embedding, vector: vec, distance: 'cosine'})
- Use a supported value: 'cosine', 'euclidean', 'taxicab', 'inner_product' (plus 'chebyshev' only for exact OpenSearch)
Example fix
# before
searchkick knn: {embedding: {dimensions: 384}}
Product.search('*', knn: {field: :embedding, vector: vec})
# => ArgumentError: distance required
# after
searchkick knn: {embedding: {dimensions: 384, distance: 'cosine'}}
Product.search('*', knn: {field: :embedding, vector: vec}) Defensive patterns
Strategy: validation
Validate before calling
def knn_query(vector, field: :embedding)
distance = Product.searchkick_options.dig(:knn, field)&.fetch(:distance, nil) || 'cosine'
Product.search('*', knn: {field: field, vector: vector, distance: distance})
end Try / catch
begin
Product.search('*', knn: opts)
rescue ArgumentError => e
raise if e.message != 'distance required'
opts = opts.merge(distance: 'cosine')
Product.search('*', knn: opts)
end Prevention
- Always declare distance in the model's searchkick knn mapping so per-query omission is safe
- Wrap query building in a helper that defaults the metric
- Fail fast at boot: assert every knn field in searchkick options declares distance and dimensions
When it happens
Trigger: Product.search('*', knn: {field: :embedding, vector: vec}) with no :distance in either place; declaring searchkick knn: {embedding: {dimensions: 384}} on the model but forgetting distance: 'cosine'.
Common situations: First time wiring up embeddings after adding a vector column; copy-pasting model code that omitted the distance key; passing the metric under a different key name such as metric: or similarity:.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- The `elasticsearch` gem must be 8+
- Redis not configured
- Need primary key to load records
- #{class_name} is not a searchkick model
- Unknown distance: #{distance}
AI-assisted analysis of ankane/searchkick@93e901a75b (2026-08-21).
Data as JSON: /api/errors/c2b4ec76ccef9629.
Report an issue: GitHub.