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
    end

View on GitHub (pinned to 93e901a75b)

Solutions

  1. Pass the same distance as the model mapping, or omit knn[:distance] so it falls back to the mapping value
  2. If this query truly needs a different metric, pass exact: true (brute-force script scoring - slower but metric-independent)
  3. 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

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


AI-assisted analysis of ankane/searchkick@93e901a75b (2026-08-21). Data as JSON: /api/errors/46ebf83a0502206d. Report an issue: GitHub.