{"record":{"id":"b8ffb2400a04871a","repo":"NationalSecurityAgency/ghidra","slug":"error-b8ffb2","errorCode":null,"errorMessage":"{}","messagePattern":"\\{\\}","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/file/H2VectorTable.java","lineNumber":136,"sourceCode":"\t * @throws SQLException if error occurs\n\t */\n\tpublic Map<Long, VectorStoreEntry> readVectors() throws SQLException {\n\t\tchar[] vectorDecodeBuffer = Base64VectorFactory.allocateBuffer();\n\t\tHashMap<Long, VectorStoreEntry> map = new HashMap<>();\n\t\ttry (Statement st = db.createStatement();\n\t\t\t\tResultSet rs = st.executeQuery(\"SELECT id,count,vec FROM \" + TABLE_NAME)) {\n\t\t\twhile (rs.next()) {\n\t\t\t\tlong id = rs.getLong(1);\n\t\t\t\tint count = rs.getInt(2);\n\t\t\t\tReader r = new StringReader(rs.getString(3));\n\t\t\t\tLSHVector vec = vectorFactory.restoreVectorFromBase64(r, vectorDecodeBuffer);\n\t\t\t\tVectorStoreEntry entry =\n\t\t\t\t\tnew VectorStoreEntry(id, vec, count, vectorFactory.getSelfSignificance(vec));\n\t\t\t\tmap.put(id, entry);\n\t\t\t}\n\t\t}\n\t\tcatch (IOException e) {\n\t\t\tthrow new SQLException(e); // unexpected for StringReader\n\t\t}\n\t\treturn map;\n\t}\n\n\t/**\n\t * Get vector details which correspond to specified vector ID\n\t * @param id vector ID\n\t * @return vector details\n\t * @throws SQLException if error occurs\n\t */\n\tpublic VectorResult queryVectorById(long id) throws SQLException {\n\n\t\tVectorStoreEntry entry = vectorStore.getVectorById(id);\n\t\tif (entry != null) {\n\t\t\treturn new VectorResult(id, entry.count(), 0, 0, entry.vec());\n\t\t}\n\n\t\tPreparedStatement s = select_by_rowid_stmt.prepareIfNeeded(","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/file/H2VectorTable.java#L118-L154","documentation":"Thrown as an SQLException wrapping an IOException by H2VectorTable.readVectors() when restoring a vector from its Base64-encoded representation fails. The readVectors() method iterates all rows in h2_vectable and calls vectorFactory.restoreVectorFromBase64() for each; an IOException here means the stored Base64 vector data is malformed or cannot be decoded into a valid LSHVector.","triggerScenarios":"Occurs when restoreVectorFromBase64() throws IOException for any row during the full table scan. This happens when: the vec column contains truncated or corrupted Base64 data, a character encoding mismatch occurred during storage, the vector factory version changed and cannot decode the old format, or the CLOB data was partially overwritten.","commonSituations":"Database was created with an older Ghidra/BSim version whose vector encoding format differs. File-level corruption of the H2 database. The CLOB column was truncated due to storage limits. A failed or partial database migration altered vector data.","solutions":["Identify which vector row(s) have corrupt data by querying the table and attempting decode row-by-row.","If the encoding format changed between versions, rebuild the database with the current Ghidra version.","Check for H2 database file corruption and run H2 recovery tools.","If only a few rows are affected, delete the corrupt vectors and re-insert them from the source program."],"exampleFix":"// before\ntry {\n    return vectorTable.readVectors();\n} catch (SQLException e) {\n    // opaque wrapping of IOException\n}\n\n// after (identify the bad row)\nMap<Long, VectorStoreEntry> map = new HashMap<>();\ntry (Statement st = db.createStatement();\n        ResultSet rs = st.executeQuery(\"SELECT id,count,vec FROM \" + TABLE_NAME)) {\n    while (rs.next()) {\n        long id = rs.getLong(1);\n        try {\n            LSHVector vec = vectorFactory.restoreVectorFromBase64(\n                new StringReader(rs.getString(3)), buf);\n            map.put(id, new VectorStoreEntry(id, vec, rs.getInt(2), 0));\n        } catch (IOException e) {\n            Msg.warn(this, \"Skipping corrupt vector id=\" + id);\n        }\n    }\n}","handlingStrategy":"try-catch","validationCode":"// Verify vector data is decodable for a sample before full read\ntry (Statement st = db.createStatement();\n        ResultSet rs = st.executeQuery(\"SELECT id,vec FROM \" + TABLE_NAME + \" LIMIT 1\")) {\n    if (rs.next()) {\n        vectorFactory.restoreVectorFromBase64(\n            new StringReader(rs.getString(2)), buf);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return vectorTable.readVectors();\n} catch (SQLException e) {\n    if (e.getCause() instanceof IOException) {\n        // One or more vectors have corrupt data\n        // Read row-by-row, skipping corrupt entries\n        return readVectorsTolerant(vectorTable);\n    }\n    throw e;\n}","preventionTips":["Do not switch Ghidra/BSim versions on an existing database without verifying vector format compatibility.","Back up BSim databases before upgrades.","If using H2, ensure the CLOB column is not truncated by storage limits.","Run readVectors() after any database migration to catch corruption early."],"tags":["bsim","h2","vector","data-corruption","base64","decode"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}