ankane/searchkick · error · ArgumentError
unknown keywords: #{unknown_keywords.join(", ")}
Error message
unknown keywords: #{unknown_keywords.join(", ")} What it means
The `searchkick` class macro validates its keyword arguments against a hardcoded allow-list (`:batch_size, :callbacks, :index_name, :knn, :language, ...` and ~45 more). Any key not on the list means you misspelled an option, passed a query-time option at model level, or used an option from a newer/older searchkick version — the unknown keys are collected and reported in one `ArgumentError` at class-load (boot) time.
Source
Thrown at lib/searchkick/model.rb:19
module Searchkick
module Model
def searchkick(**options)
options = Searchkick.model_options.deep_merge(options)
if options[:conversions]
Searchkick.warn("The `conversions` option is deprecated in favor of `conversions_v2`, which provides much better search performance. Upgrade to `conversions_v2` or rename `conversions` to `conversions_v1`")
end
if options.key?(:conversions_v1)
options[:conversions] = options.delete(:conversions_v1)
end
unknown_keywords = options.keys - [:_all, :_type, :batch_size, :callbacks, :callback_options, :case_sensitive, :conversions, :conversions_v2, :deep_paging, :default_fields,
:filterable, :geo_shape, :highlight, :ignore_above, :index_name, :index_prefix, :inheritance, :job_options, :knn, :language,
:locations, :mappings, :match, :max_result_window, :merge_mappings, :routing, :searchable, :search_synonyms, :settings, :similarity,
:special_characters, :stem, :stemmer, :stem_conversions, :stem_exclusion, :stemmer_override, :suggest, :synonyms, :text_end,
:text_middle, :text_start, :unscope, :word, :word_end, :word_middle, :word_start]
raise ArgumentError, "unknown keywords: #{unknown_keywords.join(", ")}" if unknown_keywords.any?
raise "Only call searchkick once per model" if respond_to?(:searchkick_index)
Searchkick.models << self
options[:_type] ||= -> { searchkick_index.klass_document_type(self, true) }
options[:class_name] = model_name.name
callbacks = options.key?(:callbacks) ? options[:callbacks] : :inline
unless [:inline, true, false, :async, :queue].include?(callbacks)
raise ArgumentError, "Invalid value for callbacks"
end
callback_options = (options[:callback_options] || {}).dup
callback_options[:if] = [-> { Searchkick.callbacks?(default: callbacks) }, callback_options[:if]].compact.flatten(1)
base = self
mod = Module.newView on GitHub (pinned to 93e901a75b)
Solutions
- Read the listed keys and fix each typo against the allow-list in lib/searchkick/model.rb:13-16.
- Move query-time options (`where`, `order`, `limit`, `per_page`, `fields`, `misspellings`, ...) out of the `searchkick` macro — they belong in `Model.search(...)` calls.
- Check `Searchkick::VERSION` and the README section for your gem version to confirm the option exists; pin your Gemfile to the version whose docs you read.
- After fixing, run a one-off boot (`rails runner 'puts Product'`) in CI so bad options fail the build, not production.
Example fix
# before
class Product < ApplicationRecord
searchkick index_name: "products", feilds: [:name], per_page: 20
end # => ArgumentError: unknown keywords: feilds, per_page
# after
class Product < ApplicationRecord
searchkick index_name: "products", searchable: [:name]
end
Product.search("milk", per_page: 20) Defensive patterns
Strategy: validation
Validate before calling
# Fail at boot with your own message instead of the raw ArgumentError
MODEL_OPTIONS = %i[index_name searchable filterable language callbacks batch_size knn].freeze
opts = {index_name: "products", searchable: %i[name]}
unknown = opts.keys - MODEL_OPTIONS
raise ArgumentError, "bad searchkick options: #{unknown.join(', ')}" if unknown.any?
class Product < ApplicationRecord
searchkick **opts
end Type guard
def valid_searchkick_options?(opts) allowed = %i[_all _type batch_size callbacks callback_options case_sensitive conversions conversions_v2 deep_paging default_fields filterable geo_shape highlight ignore_above index_name index_prefix inheritance job_options knn language locations mappings match max_result_window merge_mappings routing searchable search_synonyms settings similarity special_characters stem stemmer stem_conversions stem_exclusion stemmer_override suggest synonyms text_end text_middle text_start unscope word word_end word_middle word_start] (opts.keys - allowed).empty? end
Prevention
- Load one representative model in CI (`rails runner 'puts Product.name'`) so bad options break the build.
- Keep model-level and query-level options in a cheat sheet; never mix them.
- Lock the searchkick gem version in the Gemfile and read the README at that tag.
When it happens
Trigger: `searchkick feilds: [...]` (typo), `searchkick where: {...}` or `searchkick per_page: 20` (query-time options used at model level), or `searchkick scope_name: :foo` / any option added in a different searchkick version. Raises the moment the model class is loaded.
Common situations: Upgrading/downgrading the gem: an option that exists in v5 but not v4 (or vice versa) kills the app at boot; copying a config snippet from README HEAD while running an older gem; muscle-memory from other gems (elasticsearch-model, chewy) whose option names differ; silent Ruby behavior where a misspelled keyword becomes an unknown key rather than a syntax error.
Related errors
- Unknown stemmer: #{stemmer[:type]}
- Invalid value for callbacks
- unknown keywords: #{unknown_keywords.join(", ")}
- Multiple clients found - set Searchkick.client_type = :elast
- No client found - install the `elasticsearch` or `opensearch
AI-assisted analysis of ankane/searchkick@93e901a75b (2026-08-21).
Data as JSON: /api/errors/a4fc428e306953f0.
Report an issue: GitHub.