{"record":{"id":"a1370b730993ac0a","repo":"NationalSecurityAgency/ghidra","slug":"bad-vector-table-rowid","errorCode":null,"errorMessage":"Bad vector table rowid","messagePattern":"Bad vector table rowid","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/file/H2FileFunctionDatabase.java","lineNumber":208,"sourceCode":"\t\t\tpasswordChangeRequest.passwordResponse.changeSuccessful = false;\n\t\t\tpasswordChangeRequest.passwordResponse.errorMessage =\n\t\t\t\t\"Unsupported operation for H2 backend\";\n\t\t}\n\t\telse if (query instanceof AdjustVectorIndex q) {\n\t\t\tq.buildResponseTemplate();\n\t\t\tq.adjustresponse.operationSupported = false;\n\t\t}\n\t\telse {\n\t\t\treturn super.doQuery(query, c);\n\t\t}\n\t\treturn query.getResponse();\n\t}\n\n\t@Override\n\tprotected VectorResult queryVectorId(long id) throws SQLException {\n\t\tVectorResult rowres = vectorTable.queryVectorById(id);\n\t\tif (rowres == null) {\n\t\t\tthrow new SQLException(\"Bad vector table rowid\");\n\t\t}\n\t\treturn rowres;\n\t}\n\n\t@Override\n\tprotected long storeSignatureRecord(SignatureRecord sigrec) throws SQLException {\n\t\t// NOTE: ignore sigrec count - assume only one (1)\n\t\treturn vectorTable.updateVector(sigrec.getLSHVector(), 1);\n\t}\n\n\t@Override\n\tprotected int queryNearestVector(List<VectorResult> resultset, LSHVector vec, double simthresh,\n\t\t\tdouble sigthresh, int max) throws SQLException {\n\t\tVectorCompare comp;\n\t\tList<VectorResult> resultsToSort = new ArrayList<>();\n\t\tfor (VectorStoreEntry entry : vectorStore) {\n\t\t\tif (entry.selfSig() < sigthresh) {\n\t\t\t\tcontinue;","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/file/H2FileFunctionDatabase.java#L190-L226","documentation":"Thrown as an SQLException by H2FileFunctionDatabase.queryVectorId() when vectorTable.queryVectorById(id) returns null. This indicates the requested vector ID does not correspond to any row in the h2_vectable, meaning a stale or invalid vector ID was passed to the query layer.","triggerScenarios":"Occurs when queryVectorId() is called (typically during query resolution that resolves functions to their vectors) with an ID that has no matching row. This can happen when: the vector was deleted between query construction and execution, the ID came from a stale cache, or there is a data integrity issue where a function/description references a vector ID that doesn't exist.","commonSituations":"Concurrent modification of the database (one thread deletes vectors while another queries). Using a cached vector ID after the database was rebuilt. Data corruption or partial database migration. Race condition between insert and query in a multi-threaded context.","solutions":["Check for concurrent modifications to the database — ensure no other process is deleting vectors during queries.","If the vector ID comes from a cached result, refresh the cache from the database.","If the database was rebuilt, re-run the query from scratch rather than using stale IDs.","Run readVectorMap() to verify which vector IDs currently exist and compare with the failing ID."],"exampleFix":"// before\nVectorResult res = db.queryVectorId(staleId); // throws\n\n// after\nMap<Long, VectorStoreEntry> validIds = db.readVectorMap();\nif (!validIds.containsKey(staleId)) {\n    // ID is stale; skip or re-query\n    return null;\n}\nVectorResult res = db.queryVectorId(staleId);","handlingStrategy":"validation","validationCode":"// Verify vector ID exists before querying\nMap<Long, VectorStoreEntry> validIds = database.readVectorMap();\nif (!validIds.containsKey(vectorId)) {\n    throw new IllegalArgumentException(\n        \"Vector ID \" + vectorId + \" does not exist in the database\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    VectorResult result = database.queryVectorId(id);\n} catch (SQLException e) {\n    if (e.getMessage().equals(\"Bad vector table rowid\")) {\n        // ID is stale or invalid; handle gracefully\n        Msg.warn(this, \"Vector ID \" + id + \" not found; skipping\");\n        return null;\n    }\n    throw e;\n}","preventionTips":["Avoid caching vector IDs across database modifications.","Use readVectorMap() to validate IDs before querying when IDs may be stale.","Ensure no concurrent modifications (deletes) are happening during queries.","Treat a 'Bad vector table rowid' as a signal of data drift and investigate the root cause."],"tags":["bsim","h2","vector","data-integrity","not-found"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}