{"record":{"id":"3febb4e90fa30d7c","repo":"ankane/searchkick","slug":"unknown-stemmer-stemmer-type","errorCode":null,"errorMessage":"Unknown stemmer: #{stemmer[:type]}","messagePattern":"Unknown stemmer: #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/searchkick/index_options.rb","lineNumber":312,"sourceCode":"            type: language\n          },\n          searchkick_search2: {\n            type: language\n          }\n        )\n      end\n    end\n\n    def update_stemming(settings)\n      if options[:stemmer]\n        stemmer = options[:stemmer]\n        # could also support snowball and stemmer\n        case stemmer[:type]\n        when \"hunspell\"\n          # supports all token filter options\n          settings[:analysis][:filter][:searchkick_stemmer] = stemmer\n        else\n          raise ArgumentError, \"Unknown stemmer: #{stemmer[:type]}\"\n        end\n      end\n\n      stem = options[:stem]\n\n      # language analyzer used\n      stem = false if settings[:analysis][:analyzer][default_analyzer][:type] != \"custom\"\n\n      if stem == false\n        settings[:analysis][:filter].delete(:searchkick_stemmer)\n        settings[:analysis][:analyzer].each do |_, analyzer|\n          analyzer[:filter].delete(\"searchkick_stemmer\") if analyzer[:filter]\n        end\n      end\n\n      if options[:stemmer_override]\n        stemmer_override = {\n          type: \"stemmer_override\"","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/ankane/searchkick/blob/93e901a75b11a25101668a616e006b158251b16e/lib/searchkick/index_options.rb#L294-L330","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)."],"exampleFix":"# before\nclass Product < ApplicationRecord\n  searchkick stemmer: {type: \"snowball\", language: \"English\"}\nend\nProduct.reindex # => ArgumentError: Unknown stemmer: snowball\n\n# after\nclass Product < ApplicationRecord\n  searchkick language: \"English\", stem_exclusion: [\"sku\"]\nend\nProduct.reindex","handlingStrategy":"validation","validationCode":"SUPPORTED_STEMMERS = %w[hunspell].freeze\n\nstemmer = {type: \"hunspell\", locale: \"en_US\"}\nraise ArgumentError, \"searchkick supports only: #{SUPPORTED_STEMMERS.join(', ')}\" unless SUPPORTED_STEMMERS.include?(stemmer[:type])\nclass Product < ApplicationRecord\n  searchkick stemmer: stemmer\nend","typeGuard":"def searchkick_stemmer_supported?(stemmer)\n  stemmer.is_a?(Hash) && %w[hunspell].include?(stemmer[:type])\nend","tryCatchPattern":null,"preventionTips":["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."],"tags":["searchkick","stemmer","index-options","configuration","argumenterror"],"backgroundTag":"invalid-configuration-value","analyzedSha":"93e901a75b11a25101668a616e006b158251b16e","analyzedAt":"2026-08-21T19:06:23.767Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}