{"record":{"id":"c8e157a2a8f64cbd","repo":"ankane/searchkick","slug":"unknown-distance-distance","errorCode":null,"errorMessage":"Unknown distance: #{distance}","messagePattern":"Unknown distance: #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/searchkick/index_options.rb","lineNumber":459,"sourceCode":"            raise ArgumentError, \"Must specify a distance for OpenSearch\"\n          end\n\n          vector_options = {\n            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\",","sourceCodeStart":441,"sourceCodeEnd":477,"githubUrl":"https://github.com/ankane/searchkick/blob/93e901a75b11a25101668a616e006b158251b16e/lib/searchkick/index_options.rb#L441-L477","documentation":"When building the OpenSearch `knn_vector` mapping, searchkick translates your `distance` string into an OpenSearch `space_type` via a fixed case statement: `\"cosine\"`→`cosinesimil`, `\"euclidean\"`→`l2`, `\"inner_product\"`→`innerproduct`. Any other value has no translation, so it raises `ArgumentError` rather than sending an invalid space_type to the server.","triggerScenarios":"`searchkick knn: {embedding: {dimensions: 768, distance: \"dot_product\"}}` (or `\"l2\"`, `\"cosinesimil\"`, `\"l2_norm\"`, or any typo) on OpenSearch, followed by reindex/index creation.","commonSituations":"Copy-pasting OpenSearch's own space_type names (`cosinesimil`, `l2`, `innerproduct`) instead of searchkick's abstracted `distance` names; copy-pasting Elasticsearch similarity names (`l2_norm`, `max_inner_product`, `dot_product`) which the OpenSearch branch does not accept; using a vector-embedding vendor's default metric name verbatim.","solutions":["Use one of the three accepted strings: `distance: \"cosine\"`, `distance: \"euclidean\"`, or `distance: \"inner_product\"`.","Do not pass raw OpenSearch space_types or ES similarities — searchkick normalizes both platforms from the three abstract values.","If you need an unsupported metric, drop to a hand-written `mappings:`/`merge_mappings` config for that field.","Reindex after changing the knn config."],"exampleFix":"# before\nsearchkick knn: {embedding: {dimensions: 768, distance: \"cosinesimil\"}}\n# OpenSearch => ArgumentError: Unknown distance: cosinesimil\n\n# after\nsearchkick knn: {embedding: {dimensions: 768, distance: \"cosine\"}}","handlingStrategy":"validation","validationCode":"SUPPORTED_DISTANCES = %w[cosine euclidean inner_product].freeze\nknn = {embedding: {dimensions: 768, distance: \"cosine\"}}\nbad = knn.select { |_, o| !SUPPORTED_DISTANCES.include?(o[:distance]) }\nraise ArgumentError, \"unsupported distances: #{bad.keys.join(', ')}\" if bad.any?\nclass Product < ApplicationRecord\n  searchkick knn: knn\nend","typeGuard":"def valid_knn_distance?(distance)\n  %w[cosine euclidean inner_product].include?(distance)\nend","tryCatchPattern":null,"preventionTips":["Use searchkick's three abstract distance names; never paste raw space_types (cosinesimil) or ES similarities (l2_norm) into `distance`.","Keep knn config in one constant so a typo fails once at boot, not per index build.","Add a spec asserting the knn mapping builds (call the private index_options in a test) after config edits."],"tags":["searchkick","opensearch","knn","distance-metric","vector-search"],"backgroundTag":"unsupported-option-value","analyzedSha":"93e901a75b11a25101668a616e006b158251b16e","analyzedAt":"2026-08-21T19:06:23.767Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}