ankane/searchkick · error · ArgumentError

All fields in per-field misspellings must also be specified

Error message

All fields in per-field misspellings must also be specified in fields option

What it means

Per-field misspellings (`misspellings: {fields: [...]}`) replace fuzziness on the default field set with fuzziness only on the listed fields, and searchkick's query builder indexes each misspelling field against the query's `fields` list. If a field appears in `misspellings[:fields]` but not in the resolved `fields` (compared after stripping multi-field suffixes via `base_field`), there is no query to attach the fuzzy variant to, so it raises `ArgumentError`.

Source

Thrown at lib/searchkick/query.rb:328

          end

          if misspellings != false
            edit_distance = (misspellings.is_a?(Hash) && (misspellings[:edit_distance] || misspellings[:distance])) || 1
            transpositions =
              if misspellings.is_a?(Hash) && misspellings.key?(:transpositions)
                {fuzzy_transpositions: misspellings[:transpositions]}
              else
                {fuzzy_transpositions: true}
              end
            prefix_length = (misspellings.is_a?(Hash) && misspellings[:prefix_length]) || 0
            default_max_expansions = @misspellings_below ? 20 : 3
            max_expansions = (misspellings.is_a?(Hash) && misspellings[:max_expansions]) || default_max_expansions
            misspellings_fields = misspellings.is_a?(Hash) && misspellings.key?(:fields) && misspellings[:fields].map(&:to_s)

            if misspellings_fields
              missing_fields = misspellings_fields - fields.map { |f| base_field(f) }
              if missing_fields.any?
                raise ArgumentError, "All fields in per-field misspellings must also be specified in fields option"
              end
            end

            @misspellings = true
          else
            @misspellings = false
          end

          fields.each do |field|
            queries_to_add = []
            qs = []

            factor = boost_fields[field] || 1
            shared_options = {
              query: term,
              boost: 10 * factor
            }

View on GitHub (pinned to 93e901a75b)

Solutions

  1. Add every misspellings field to `fields:`: `fields: [:name, :brand], misspellings: {fields: [:brand]}` (order does not matter, membership does).
  2. If you meant to search all default fields, drop the per-field hash and use `misspellings: false`/default instead.
  3. Ensure the names match the searchable attributes exactly (symbols vs strings are both fine; suffixes like `.analyzed` are normalized by base_field).
  4. Add a unit test that builds the query (`Product.search(...).to_curl` or checking `payload`) to catch this before runtime.

Example fix

# before
Product.search("milk", fields: [:name], misspellings: {fields: [:name, :brand]})
# => ArgumentError: All fields in per-field misspellings must also be specified in fields option

# after
Product.search("milk", fields: [:name, :brand], misspellings: {fields: [:brand]})
Defensive patterns

Strategy: validation

Validate before calling

def fuzzy_search(term, fields:, misspellings_fields: [])
  missing = Array(misspellings_fields).map(&:to_s) - Array(fields).map { |f| f.to_s.split(".").first }
  raise ArgumentError, "misspellings fields not in fields: #{missing.join(', ')}" if missing.any?
  Product.search(term, fields: fields, misspellings: {fields: misspellings_fields})
end

Type guard

def misspellings_subset_of_fields?(misspellings_fields, fields)
  base = fields.map { |f| f.to_s.split("^").first.to_s.split(".").first }
  Array(misspellings_fields).map(&:to_s).all? { |f| base.include?(f) }
end

Prevention

When it happens

Trigger: `Product.search("milk", fields: [:name], misspellings: {fields: [:name, :brand]})` — `:brand` is missing from `fields`. Also caught: suffix mismatches like listing `name.word_start` in misspellings fields while `fields: [:name]` (base_field handles the common cases, but a truly absent field is not).

Common situations: Disabling fuzziness for one noisy field and forgetting to add the remaining searchable fields to `fields:`; renaming an attribute in the model but not in the misspellings hash; using `fields: [{name: :exact}]`-style entries while listing plain `:name` or vice versa in misspellings.

Related errors


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