{"record":{"id":"31a0f9c2b62070e0","repo":"ankane/searchkick","slug":"quantization-not-supported-yet-for-opensearch","errorCode":null,"errorMessage":"Quantization not supported yet for OpenSearch","messagePattern":"Quantization not supported yet for OpenSearch","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/searchkick/index_options.rb","lineNumber":463,"sourceCode":"            type: \"knn_vector\",\n            dimension: knn_options[:dimensions]\n          }\n\n          if !distance.nil?\n            space_type =\n              case distance\n              when \"cosine\"\n                \"cosinesimil\"\n              when \"euclidean\"\n                \"l2\"\n              when \"inner_product\"\n                \"innerproduct\"\n              else\n                raise ArgumentError, \"Unknown distance: #{distance}\"\n              end\n\n            if !quantization.nil?\n              raise ArgumentError, \"Quantization not supported yet for OpenSearch\"\n            end\n\n            vector_options[:method] = {\n              name: \"hnsw\",\n              space_type: space_type,\n              engine: \"lucene\",\n              parameters: knn_options.slice(:m, :ef_construction)\n            }\n          end\n\n          mapping[field.to_s] = vector_options\n        else\n          vector_options = {\n            type: \"dense_vector\",\n            dims: knn_options[:dimensions],\n            index: !distance.nil?\n          }\n","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/ankane/searchkick/blob/93e901a75b11a25101668a616e006b158251b16e/lib/searchkick/index_options.rb#L445-L481","documentation":"In the OpenSearch branch of the knn mapping builder, quantization (`int8`/`int4`/`bbq`) is a Lucene/Elasticsearch feature; OpenSearch's `knn_vector` `method` block has no equivalent parameter. Since searchkick cannot map it, it raises `ArgumentError` whenever `quantization` is non-nil on OpenSearch, even if the distance itself is valid.","triggerScenarios":"`searchkick knn: {embedding: {dimensions: 768, distance: \"cosine\", quantization: \"int8\"}}` while `Searchkick.opensearch?` is true, then reindex. The check runs right after the distance case statement, so any valid distance plus any quantization value triggers it.","commonSituations":"Sharing one model config between an Elasticsearch dev environment and an OpenSearch production environment (common with Amazon OpenSearch Service); following the README's ES scalar-quantization examples on OpenSearch; enabling quantization to shrink a large embedding index without checking engine support.","solutions":["Remove `quantization:` from the knn options when targeting OpenSearch.","Make the option conditional on engine: `knn: {embedding: {dimensions: 768, distance: \"cosine\"}.merge(Searchkick.opensearch? ? {} : {quantization: \"int8\"})}`.","If memory is the concern on OpenSearch, tune `m`/`ef_construction` (passed through as method parameters) or reduce `dimensions` instead.","Switch the index to Elasticsearch if scalar quantization is a hard requirement."],"exampleFix":"# before\nsearchkick knn: {embedding: {dimensions: 768, distance: \"cosine\", quantization: \"int8\"}}\n# OpenSearch => ArgumentError: Quantization not supported yet for OpenSearch\n\n# after\nknn_opts = {dimensions: 768, distance: \"cosine\"}\nknn_opts[:quantization] = \"int8\" unless Searchkick.opensearch?\nsearchkick knn: {embedding: knn_opts}","handlingStrategy":"validation","validationCode":"knn = {embedding: {dimensions: 768, distance: \"cosine\"}}\nknn.each_value { |o| o.delete(:quantization) } if Searchkick.opensearch?\nclass Product < ApplicationRecord\n  searchkick knn: knn\nend","typeGuard":"def knn_engine_compatible?(knn, opensearch:)\n  !opensearch || knn.all? { |_, o| o[:quantization].nil? }\nend","tryCatchPattern":null,"preventionTips":["Branch engine-specific knn options on `Searchkick.opensearch?` in one config helper.","Document in the model comment that quantization is ES-only so teammates don't re-add it.","Run `Model.reindex` in a staging environment identical to production engine before deploy."],"tags":["searchkick","opensearch","knn","quantization","vector-search"],"backgroundTag":"unsupported-feature-combination","analyzedSha":"93e901a75b11a25101668a616e006b158251b16e","analyzedAt":"2026-08-21T19:06:23.767Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}