{"record":{"id":"2cf851f4d96800c3","repo":"NationalSecurityAgency/ghidra","slug":"could-not-find-hits-document","errorCode":null,"errorMessage":"Could not find hits document","messagePattern":"Could not find hits document","errorType":"exception","errorClass":"ElasticException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java","lineNumber":850,"sourceCode":"\t\tbuffer.append(\"    \\\"min_score\\\": 0.00001, \");\t\t// Make sure a 0.0 score is filtered\n\t\tbuffer.append(\"    \\\"boost_mode\\\": \\\"replace\\\", \");\n\t\tbuffer.append(\"    \\\"functions\\\": [ { \");\n\t\tbuffer.append(\"      \\\"script_score\\\": { \");\n\t\tbuffer.append(\"        \\\"script\\\": { \");\n\t\tbuffer.append(\"          \\\"lang\\\": \\\"bsim_scripts\\\", \");\n\t\tbuffer.append(\"          \\\"source\\\": \\\"lsh_compare\\\", \");\n\t\tbuffer.append(\"          \\\"params\\\": { \");\n\t\tbuffer.append(\"            \\\"indexname\\\": \\\"lsh_\").append(repository).append(\"\\\", \");\n\t\tbuffer.append(\"            \\\"vector\\\": \\\"\");\n\t\tbuffer.append(vecEncode);\n\t\tbuffer.append(\"\\\",          \\\"simthresh\\\": \").append(similarityThreshold);\n\t\tbuffer.append(\",            \\\"sigthresh\\\": \").append(significanceThreshold);\n\t\tbuffer.append(\" } } } } ] } } }\");\n\t\tJsonObject resp =\n\t\t\tconnection.executeStatement(ElasticConnection.GET, \"vector/_search\", buffer.toString());\n\t\tJsonObject baseHits = (JsonObject) resp.get(\"hits\");\n\t\tif (baseHits == null) {\n\t\t\tthrow new ElasticException(\"Could not find hits document\");\n\t\t}\n\t\tJsonObject totalRec = (JsonObject) baseHits.get(\"total\");\n\t\tlong numHits = totalRec.get(\"value\").getAsLong();\n\t\tif (numHits == 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tJsonArray hitsArray = (JsonArray) baseHits.get(\"hits\");\n\t\tchar[] decodeBuffer = Base64VectorFactory.allocateBuffer();\n\t\tVectorCompare vecCompare = new VectorCompare();\n\t\ttry {\n\t\t\tint returnedHits = hitsArray.size();\n\t\t\tfor (int i = 0; i < returnedHits; ++i) {\n\t\t\t\tJsonObject mainHit = (JsonObject) hitsArray.get(i);\n\t\t\t\tVectorResult vecRes = new VectorResult();\n\t\t\t\tvecRes.vectorid = Base64Lite.decodeLongBase64(mainHit.get(\"_id\").getAsString());\n\t\t\t\tvecRes.hitcount = -1;\t\t// Cannot fill in at this time\n\t\t\t\tvecRes.sim = mainHit.get(\"_score\").getAsDouble();\n\t\t\t\tJsonObject source = (JsonObject) mainHit.get(\"_source\");","sourceCodeStart":832,"sourceCodeEnd":868,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java#L832-L868","documentation":"Thrown in queryNearestVector after issuing a GET vector/_search request with a lsh_compare script_score query. The Elasticsearch response JSON object does not contain a top-level \"hits\" key (baseHits == null). The BSim query protocol assumes every search response carries a hits document; its absence means the server returned an unexpected response shape, typically because the custom bsim_scripts plugin (lsh_compare) is missing or the script threw an internal error that did not surface as an HTTP-level failure.","triggerScenarios":"Calling queryNearestVector (reached via QueryNearest commands or any similarity search). The lsh_compare script_score sub-query returns a JSON response whose top-level keys do not include \"hits\". This happens when the repository_vector index exists but the bsim_scripts plugin script is not registered, when the script errors internally and Elasticsearch wraps the error in a non-standard envelope, or when a proxy modifies the response body.","commonSituations":"Elasticsearch server lacks the BSim plugin (bsim_scripts / lsh_tokenizer); querying a database whose vector index was partially created; Elasticsearch major-version upgrade that changed the search response envelope; HTTP proxy or load balancer stripping fields from the response.","solutions":["Verify the BSim Elasticsearch plugin is installed on every node (bin/elasticsearch-plugin list should include the lsh plugin) and restart the cluster if it was just added.","Confirm the vector index exists and was created via createVectorIndex by checking that initialize/generate completed successfully for this repository.","Issue the same vector/_search POST manually via curl against the Elasticsearch server and inspect the raw response for the hits key or an embedded error.","Ensure the Elasticsearch server version is compatible with LAYOUT_VERSION 3 as implemented by this ElasticDatabase class."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before querying, verify the vector index and plugin are healthy\nElasticConnection conn = database.getConnection(); // if accessible\nJsonObject settings = conn.executeURIOnly(ElasticConnection.GET, \"vector/_settings\");\nif (settings == null || !settings.toString().contains(\"lsh_\")) {\n    throw new IllegalStateException(\"BSim lsh tokenizer plugin not configured on server\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    database.query(queryNearest);\n} catch (ElasticException e) {\n    if (e.getMessage().contains(\"Could not find hits document\")) {\n        // Server-side plugin or index issue; not retryable without infra fix\n        Msg.error(this, \"Vector search failed — verify BSim plugin installation: \" + e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Verify the BSim Elasticsearch plugin is installed on all cluster nodes before creating or querying the database.","Run a health check query (vector/_settings) after initialize() to confirm the lsh tokenizer is present.","Document the required Elasticsearch plugin version alongside the BSim LAYOUT_VERSION in deployment guides."],"tags":["elasticsearch","bsim","query","response-parsing","plugin","lsh-compare"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}