ankane/searchkick · error · Searchkick::Error
knn requires OpenSearch 2.4+
Error message
knn requires OpenSearch 2.4+
What it means
reindex(resume: true) skips already-indexed records by comparing against the index's total docs using relation.primary_key and an arel greater-than condition - Active Record only API. Mongoid relations do not respond to primary_key, so resume_relation raises Error 'Resume not supported for Mongoid'.
Source
Thrown at lib/searchkick/index_options.rb:175
if Searchkick.env == "test"
settings[:number_of_shards] = 1
settings[:number_of_replicas] = 0
end
if options[:similarity]
settings[:similarity] = {default: {type: options[:similarity]}}
end
settings[:index] = {
max_ngram_diff: 49,
max_shingle_diff: 4
}
if options[:knn]
unless Searchkick.knn_support?
if Searchkick.opensearch?
raise Error, "knn requires OpenSearch 2.4+"
else
raise Error, "knn requires Elasticsearch 8.6+"
end
end
if Searchkick.opensearch? && options[:knn].any? { |_, v| !v[:distance].nil? }
# only enable if doing approximate search
settings[:index][:knn] = true
end
end
add_synonyms(settings)
add_search_synonyms(settings)
if options[:special_characters] == false
settings[:analysis][:analyzer].each_value do |analyzer_settings|
analyzer_settings[:filter].reject! { |f| f == "asciifolding" }
endView on GitHub (pinned to 93e901a75b)
Solutions
- Run the full reindex without resume: Product.reindex
- For long-running Mongoid reindexes, use mode: :async or :queue with batches and restart from scratch on failure
- Narrow the work with a where(...) scope instead of resuming
Example fix
# before Product.reindex(resume: true) # Mongoid model # => Searchkick::Error: Resume not supported for Mongoid # after Product.reindex # full reindex, no resume # or scope the work Product.where(created_at: 2.days.ago..).reindex
Defensive patterns
Strategy: validation
Validate before calling
def reindex_with_resume?(relation) relation.respond_to?(:primary_key) # Active Record only end Product.reindex(resume: reindex_with_resume?(Product.all) && user_wants_resume)
Try / catch
begin Product.reindex(resume: true) rescue Searchkick::Error => e raise unless e.message == 'Resume not supported for Mongoid' Product.reindex # full reindex fallback end
Prevention
- Gate resume: true behind a respond_to?(:primary_key) check for shared codebases
- For Mongoid, run reindexes in batches scoped by time/id instead of resuming
- Document ORM differences where teams mix ActiveRecord and Mongoid
When it happens
Trigger: Calling Product.reindex(resume: true) on a Mongoid model - commonly when resuming an interrupted reindex job or when scripts always pass resume: true after a failure.
Common situations: Recovering a large interrupted reindex on a Mongoid app; copy-pasting resume flows from ActiveRecord-based projects; automation that passes resume: true unconditionally.
Related errors
- wait only available in :async mode
- Full reindex does not support :queue mode - use :async mode
- No index to resume
- #{first_with_error["error"]} on item with id '#{first_with_e
- The `conversions` option is deprecated in favor of `conversi
AI-assisted analysis of ankane/searchkick@93e901a75b (2026-08-21).
Data as JSON: /api/errors/ce3b1c5acd393808.
Report an issue: GitHub.