ankane/searchkick · error · ArgumentError
Unknown stemmer: #{stemmer[:type]}
Error message
Unknown stemmer: #{stemmer[:type]} What it means
Searchkick's `update_stemming` builds the index analysis chain and only accepts one stemmer type: `"hunspell"`. Any other value in `searchkick stemmer: {type: ...}` falls through the case statement and raises `ArgumentError` at index-options build time (i.e. when creating or reindexing the index). The comment in the source notes that snowball/porter_stemmer could be supported, but they are not implemented in this version.
Source
Thrown at lib/searchkick/index_options.rb:312
type: language
},
searchkick_search2: {
type: language
}
)
end
end
def update_stemming(settings)
if options[:stemmer]
stemmer = options[:stemmer]
# could also support snowball and stemmer
case stemmer[:type]
when "hunspell"
# supports all token filter options
settings[:analysis][:filter][:searchkick_stemmer] = stemmer
else
raise ArgumentError, "Unknown stemmer: #{stemmer[:type]}"
end
end
stem = options[:stem]
# language analyzer used
stem = false if settings[:analysis][:analyzer][default_analyzer][:type] != "custom"
if stem == false
settings[:analysis][:filter].delete(:searchkick_stemmer)
settings[:analysis][:analyzer].each do |_, analyzer|
analyzer[:filter].delete("searchkick_stemmer") if analyzer[:filter]
end
end
if options[:stemmer_override]
stemmer_override = {
type: "stemmer_override"View on GitHub (pinned to 93e901a75b)
Solutions
- Use the supported type: `searchkick stemmer: {type: "hunspell", locale: "en_US"}` with a hunspell dictionary installed on the search server.
- If you just want standard language stemming, drop `stemmer:` entirely and use `searchkick language: "English"` (or set `stem_exclusion:`/`stemmer_override:` for fine-tuning).
- If you truly need snowball, build the analysis chain yourself via the `settings:`/`mappings:` options with `merge_mappings`, bypassing `stemmer:`.
- Upgrade searchkick and re-check lib/searchkick/index_options.rb — newer versions may add snowball support (the source comment flags it as a possible addition).
Example fix
# before
class Product < ApplicationRecord
searchkick stemmer: {type: "snowball", language: "English"}
end
Product.reindex # => ArgumentError: Unknown stemmer: snowball
# after
class Product < ApplicationRecord
searchkick language: "English", stem_exclusion: ["sku"]
end
Product.reindex Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED_STEMMERS = %w[hunspell].freeze
stemmer = {type: "hunspell", locale: "en_US"}
raise ArgumentError, "searchkick supports only: #{SUPPORTED_STEMMERS.join(', ')}" unless SUPPORTED_STEMMERS.include?(stemmer[:type])
class Product < ApplicationRecord
searchkick stemmer: stemmer
end Type guard
def searchkick_stemmer_supported?(stemmer) stemmer.is_a?(Hash) && %w[hunspell].include?(stemmer[:type]) end
Prevention
- Centralize searchkick model options in one initializer/config object validated at boot instead of scattering literals across models.
- Add a boot smoke test (rails runner 'Model.searchkick_options') in CI so unsupported options fail the build.
- Check the gem's index_options.rb allow-list when adopting token-filter features new to your searchkick version.
When it happens
Trigger: Calling `searchkick stemmer: {type: "snowball", language: "English"}` (or `porter_stemmer`, `kstem`, or any string other than `"hunspell"`) on a model, then running `Model.reindex` or any operation that builds index settings (create index, import).
Common situations: Copying a snowball/kstem config from a raw Elasticsearch tutorial or a different gem (e.g. chewy) into searchkick's `stemmer` option; upgrading searchkick and assuming generic token-filter options pass through; typo'ing the type string. Also hitting this after trying to combine `language:` with a custom stemmer.
Related errors
- unknown keywords: #{unknown_keywords.join(", ")}
- Invalid value for callbacks
- Multiple clients found - set Searchkick.client_type = :elast
- No client found - install the `elasticsearch` or `opensearch
- The `elasticsearch` gem must be 8+
AI-assisted analysis of ankane/searchkick@93e901a75b (2026-08-21).
Data as JSON: /api/errors/3febb4e90fa30d7c.
Report an issue: GitHub.