{"record":{"id":"9ebcff3d79506944","repo":"NationalSecurityAgency/ghidra","slug":"id-mismatch-when-inserting-executable","errorCode":null,"errorMessage":"Id mismatch when inserting executable: ","messagePattern":"Id mismatch when inserting executable: ","errorType":"exception","errorClass":"LSHException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java","lineNumber":1059,"sourceCode":"\tprivate void testExecutableDuplication(DescriptionManager input)\n\t\t\tthrows SQLException, LSHException, DatabaseNonFatalException {\n\t\tboolean pickout_storedfuncs = false;\n\t\tfor (ExecutableRecord erec : input.getExecutableRecordSet()) {\n\t\t\tExecutableRow row = exeTable.queryMd5ExeMatch(erec.getMd5());\n\t\t\tif (row != null) { // Already have a matching executable\n\t\t\t\tExecutableRecord tmp = makeExecutableRecordTemp(row);\n\t\t\t\tint cmp = tmp.compareMetadata(erec);\n\t\t\t\tif (cmp != 0) {\n\t\t\t\t\tString fatalerror = FunctionDatabase.constructFatalError(cmp, erec, tmp);\n\t\t\t\t\tif (fatalerror != null) {\n\t\t\t\t\t\tthrow new LSHException(fatalerror);\n\t\t\t\t\t}\n\t\t\t\t\tthrow new DatabaseNonFatalException(\n\t\t\t\t\t\tFunctionDatabase.constructNonfatalError(cmp, erec, tmp));\n\t\t\t\t}\n\t\t\t\tif (erec.getRowId() != null) {\n\t\t\t\t\tif (!erec.getRowId().equals(tmp.getRowId())) {\n\t\t\t\t\t\tthrow new LSHException(\n\t\t\t\t\t\t\t\"Id mismatch when inserting executable: \" + erec.getNameExec());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tinput.setExeRowId(erec, tmp.getRowId());\n\t\t\t\t}\n\t\t\t\tinput.setExeAlreadyStored(erec);\n\t\t\t\t// Just because we've seen a library before doesn't mean we should stop function insertion\n\t\t\t\t// Libraries are likely to be partially inserted multiple times\n\t\t\t\tif (!erec.isLibrary()) {\n\t\t\t\t\tthrow new DatabaseNonFatalException(\n\t\t\t\t\t\terec.getNameExec() + \" is already ingested\");\n\t\t\t\t}\n\t\t\t\tpickout_storedfuncs = true; // At least one executable has previously inserted functions\n\t\t\t}\n\t\t}\n\n\t\tif (pickout_storedfuncs) {","sourceCodeStart":1041,"sourceCodeEnd":1077,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java#L1041-L1077","documentation":"In `testExecutableDuplication`, when an incoming executable's metadata matches an existing record, but the incoming record already carries a rowId that differs from the stored one, LSHException is thrown. Equal metadata with disagreeing IDs signals inconsistent state that would corrupt cross-table linkage, so the insert is refused.","triggerScenarios":"Re-inserting an executable through a path that pre-assigned a rowId different from the DB's -- typically concurrent/cross-connection inserts sharing a DescriptionManager, or resuming an aborted ingest with stale ID assignments.","commonSituations":"Parallel ingest processes against the same DB; reusing a DescriptionManager across databases; DB restored from a partial/inconsistent backup; idempotent-retry logic that preserved IDs.","solutions":["Restart the ingest with a fresh DescriptionManager carrying no pre-set rowIds.","Avoid concurrent ingests writing the same DB; serialize writers.","Verify DB integrity and confirm no partial-state rows remain."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure incoming executables carry NO pre-set rowId before insert.\nfor (ExecutableRecord erec : manager.getAllExecutables()) {\n    if (erec.getRowId() != null) {\n        throw new IllegalStateException(\n            \"Input executable has pre-set rowId; rebuild DescriptionManager: \" + erec.getNameExec());\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    db.insert(manager);\n} catch (LSHException e) {\n    if (e.getMessage().startsWith(\"Id mismatch when inserting executable:\")) {\n        // inconsistent state -- abort the batch and restart with a clean manager\n        throw new IngestStateInconsistentException(e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Use a single writer (serialize ingests) against a given DB.","Never reuse a DescriptionManager across databases or resumed sessions with stale IDs.","Treat ID mismatch as corruption and restart the ingest batch cleanly."],"tags":["database","insert","concurrency","corruption","bsim"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}