{"record":{"id":"05527505bfaa0b84","repo":"NationalSecurityAgency/ghidra","slug":"already-inserted","errorCode":null,"errorMessage":"Already inserted","messagePattern":"Already inserted","errorType":"exception","errorClass":"DatabaseNonFatalException","httpStatus":null,"severity":"warning","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java","lineNumber":1079,"sourceCode":"\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) {\n\t\t\tif (!markPreviouslyStoredFunctions(input, input.listAllFunctions())) {\n\t\t\t\tthrow new DatabaseNonFatalException(\"Already inserted\");\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Do the final work of inserting new ExecutableRecords into the database. This function\n\t * assumes testExecutableDuplication has already run and marked previously ingested records\n\t * \n\t * @param input the executable descriptor\n\t * @throws SQLException if database records cannot be inserted\n\t */\n\tprivate void commitExecutables(DescriptionManager input) throws SQLException {\n\t\tIterator<ExecutableRecord> iter = input.getExecutableRecordSet().iterator();\n\t\twhile (iter.hasNext()) {\n\t\t\tExecutableRecord erec = iter.next();\n\t\t\tif (erec.isAlreadyStored()) {\n\t\t\t\tcontinue;\n\t\t\t}","sourceCodeStart":1061,"sourceCodeEnd":1097,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java#L1061-L1097","documentation":"After executable deduplication, if `pickout_storedfuncs` is set and `markPreviouslyStoredFunctions` returns false, the method throws DatabaseNonFatalException(\"Already inserted\"). A false return means every function in the batch was already present -- nothing new remains to insert.","triggerScenarios":"Inserting a batch of functions whose signatures are all already stored (prior ingest of the same executable's functions). `markPreviouslyStoredFunctions` found zero new functions and returned false.","commonSituations":"Re-running the same ingest; functions inserted earlier under a library context that overlaps the current set; idempotent retries.","solutions":["Treat DatabaseNonFatalException(\"Already inserted\") as expected and skip the batch.","Track ingested-function inventory to avoid submitting fully-duplicate batches.","Design ingest as idempotent and tolerant of this non-fatal result."],"exampleFix":"// before: batch insert repeatedly throws non-fatal, aborting the run\n// after: catch at the batch boundary and continue\ntry { db.insert(manager); }\ncatch (DatabaseNonFatalException e) {\n    log.info(\"batch already inserted: {}\", e.getMessage());\n}","handlingStrategy":"try-catch","validationCode":"// Before insert, check whether all functions in the batch are already stored.\nboolean anyNew = false;\nfor (FunctionDescription fd : manager.listAllFunctions()) {\n    if (!isAlreadyStored(fd)) { anyNew = true; break; }\n}\nif (!anyNew) log.info(\"batch fully already-inserted; skipping\");","typeGuard":null,"tryCatchPattern":"try {\n    db.insert(manager);\n} catch (DatabaseNonFatalException e) {\n    if (\"Already inserted\".equals(e.getMessage())) {\n        // entire batch was present -- expected for re-runs, continue\n        log.info(\"batch already inserted: {}\", e.getMessage());\n        return;\n    }\n    throw e;\n}","preventionTips":["Maintain an ingested-function inventory to skip fully-duplicate batches.","Design ingest as idempotent and tolerant of the non-fatal 'Already inserted'.","Deduplicate batches before submission."],"tags":["database","insert","duplicate","non-fatal","function","bsim"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}