ankane/searchkick · error · Searchkick::Error
Redis not configured
Error message
Redis not configured
What it means
Approximate kNN runs on a vector index (HNSW) that was created with the single distance metric declared in the model's searchkick options. Scoring that structure with a different metric would return wrong results, so Searchkick raises ArgumentError 'distance must match searchkick options for approximate search' unless the query distance equals the field's configured distance. Exact (brute-force script) search may use any supported metric.
Source
Thrown at lib/searchkick.rb:259
end
result
ensure
self.callbacks_value = previous_value
end
else
self.callbacks_value = value
end
end
def self.aws_credentials=(creds)
require "faraday_middleware/aws_sigv4"
@aws_credentials = creds
@client = nil # reset client
end
def self.reindex_status(index_name)
raise Error, "Redis not configured" unless redis
batches_left = Index.new(index_name).batches_left
{
completed: batches_left == 0,
batches_left: batches_left
}
end
def self.with_redis
if redis
if redis.respond_to?(:with)
redis.with do |r|
yield r
end
else
yield redis
end
endView on GitHub (pinned to 93e901a75b)
Solutions
- Pass the same distance as the model mapping, or omit knn[:distance] so it falls back to the mapping value
- If this query truly needs a different metric, pass exact: true (brute-force script scoring - slower but metric-independent)
- If the whole dataset should switch metrics, change the model's knn distance and reindex so the vector index is rebuilt
Example fix
# before
searchkick knn: {embedding: {dimensions: 768, distance: 'cosine'}}
Product.search('*', knn: {field: :embedding, vector: vec, distance: 'euclidean'})
# => ArgumentError: distance must match searchkick options for approximate search
# after (inherit mapping distance)
Product.search('*', knn: {field: :embedding, vector: vec})
# or force exact scoring with another metric
Product.search('*', knn: {field: :embedding, vector: vec, distance: 'euclidean', exact: true}) Defensive patterns
Strategy: validation
Validate before calling
def safe_knn(vector:, field:, distance: nil)
mapped = Product.searchkick_options.dig(:knn, field)&.[](:distance)
distance ||= mapped or raise ArgumentError, 'distance required'
exact = distance != mapped # different metric only allowed via exact scoring
Product.search('*', knn: {field: field, vector: vector, distance: distance, exact: exact})
end Prevention
- Single source of truth: read the distance from searchkick options instead of hardcoding per call site
- If a query needs a different metric, set exact: true deliberately in one helper
- Cover kNN queries with a test asserting the built params (Query#body) to catch metric drift
When it happens
Trigger: Model declares searchkick knn: {embedding: {dimensions: 768, distance: 'cosine'}}; query runs Product.search('*', knn: {field: :embedding, vector: vec, distance: 'euclidean', exact: false}) - mismatched distance under approximate mode raises.
Common situations: Experimenting with different similarity metrics per query without changing the mapping; changing the model's distance later while old call sites still hardcode the previous metric; copy-pasting a query from a project that used euclidean.
Related errors
- Use Searchkick.search to search multiple models
- Unknown distance: #{distance}
- The `elasticsearch` gem must be 8+
- Need primary key to load records
- Could not find class: #{class_name}
AI-assisted analysis of ankane/searchkick@93e901a75b (2026-08-21).
Data as JSON: /api/errors/46ebf83a0502206d.
Report an issue: GitHub.