ankane/searchkick · error · ArgumentError

Unknown quantization: #{quantization}

Error message

Unknown quantization: #{quantization}

What it means

On Elasticsearch, quantization is expressed through the dense-vector field `type` suffix: `int8_hnsw`, `int4_hnsw`, or `bbq_hnsw` (and plain `hnsw` when unquantized). The case statement accepts only `"int8"`, `"int4"`, `"bbq"`, or `nil`; any other quantization value has no mapping type, so searchkick raises `ArgumentError` at mapping-build time.

Source

Thrown at lib/searchkick/index_options.rb:502

              case distance
              when "cosine"
                "cosine"
              when "euclidean"
                "l2_norm"
              when "inner_product"
                "max_inner_product"
              else
                raise ArgumentError, "Unknown distance: #{distance}"
              end

            type =
              case quantization
              when "int8", "int4", "bbq"
                "#{quantization}_hnsw"
              when nil
                "hnsw"
              else
                raise ArgumentError, "Unknown quantization: #{quantization}"
              end

            vector_index_options = knn_options.slice(:m, :ef_construction)
            vector_options[:index_options] = {type: type}.merge(vector_index_options)
          end

          mapping[field.to_s] = vector_options
        end
      end

      if options[:inheritance]
        mapping[:type] = keyword_mapping
      end

      routing = {}
      if options[:routing]
        routing = {required: true}
        unless options[:routing] == true

View on GitHub (pinned to 93e901a75b)

Solutions

  1. Use `quantization: "int8"`, `"int4"`, or `"bbq"` — searchkick appends `_hnsw` itself.
  2. Omit `quantization` entirely for full-precision HNSW.
  3. Verify the ES version supports the type (bbq_hnsw needs ES 8.15+); otherwise pick int8/int4.
  4. Reindex after the change.

Example fix

# before
searchkick knn: {embedding: {dimensions: 768, distance: "cosine", quantization: "int8_hnsw"}}
# => ArgumentError: Unknown quantization: int8_hnsw

# after
searchkick knn: {embedding: {dimensions: 768, distance: "cosine", quantization: "int8"}}
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_QUANTIZATION = %w[int8 int4 bbq].freeze
quant = "int8"
raise ArgumentError, "unsupported quantization #{quant}" unless SUPPORTED_QUANTIZATION.include?(quant)
class Product < ApplicationRecord
  searchkick knn: {embedding: {dimensions: 768, distance: "cosine", quantization: quant}}
end

Type guard

def valid_knn_quantization?(quant)
  quant.nil? || %w[int8 int4 bbq].include?(quant)
end

Prevention

When it happens

Trigger: `searchkick knn: {embedding: {dimensions: 768, distance: "cosine", quantization: "int8_hnsw"}}` (passing the raw ES type instead of the abstract value), or `quantization: "float8"`, `"binary"`, or `:int8` (symbol) on Elasticsearch, then reindex.

Common situations: Copying `int8_hnsw`/`int4_hnsw` straight from Elasticsearch mapping docs into the searchkick option; using a vendor's or blog's quantization name that searchkick doesn't abstract; assuming symbols and strings are interchangeable here.

Related errors


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