{"record":{"id":"3051c4707a911c29","repo":"NationalSecurityAgency/ghidra","slug":"executable-category-already-exists","errorCode":null,"errorMessage":"Executable category already exists","messagePattern":"Executable category already exists","errorType":"validation","errorClass":"LSHException","httpStatus":null,"severity":"warning","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java","lineNumber":2197,"sourceCode":"\t * @throws SQLException if there is an error issuing the query\n\t */\n\tprivate void fdbInstallCategory(InstallCategoryRequest query)\n\t\t\tthrows LSHException, SQLException {\n\t\tResponseInfo response = query.installresponse;\n\t\tif (!CategoryRecord.enforceTypeCharacters(query.type_name)) {\n\t\t\tthrow new LSHException(\"Bad characters in proposed category type\");\n\t\t}\n\t\tif (query.isdatecolumn) {\n\t\t\tinfo.dateColumnName = query.type_name;\n\t\t\tkeyValueTable.insert(\"datecolumn\", info.dateColumnName);\n\t\t\tresponse.info = info;\n\t\t\treturn;\n\t\t}\n\t\t// Check for existing category\n\t\tif (info.execats != null) {\n\t\t\tfor (String cat : info.execats) {\n\t\t\t\tif (cat.equals(query.type_name)) {\n\t\t\t\t\tthrow new LSHException(\"Executable category already exists\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (info.execats == null) {\n\t\t\tinfo.execats = new ArrayList<>();\n\t\t}\n\t\tinfo.execats.add(query.type_name);\n\t\tkeyValueTable.writeExecutableCategories(info);\n\t\tresponse.info = info;\n\t}\n\n\t/**\n\t * Returns a list of all function tags in the database.\n\t * \n\t * @return list of function tags\n\t */\n\tpublic List<String> getFunctionTags() {\n\t\treturn info.functionTags;","sourceCodeStart":2179,"sourceCodeEnd":2215,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java#L2179-L2215","documentation":"Thrown by fdbInstallCategory when the requested category type_name already exists in info.execats (the database's executable category list). BSim prevents duplicate category columns to avoid schema ambiguity. Date columns (isdatecolumn=true) bypass this check.","triggerScenarios":"Issuing an InstallCategoryRequest for a type_name that is already present in the loaded DatabaseInformation.execats array; re-running an install script without checking existing categories.","commonSituations":"Idempotent setup scripts that re-run installation; concurrent clients both trying to install the same category; migration tooling that doesn't first query existing categories.","solutions":["Query current categories (info.execats) before installing and skip if the name already exists.","Make install scripts idempotent: check contains() before issuing the request.","Guard concurrent installs with coordination or a pre-check."],"exampleFix":"// before\ndb.execute(installReq); // may already exist\n// after\nif (info.execats == null || !info.execats.contains(req.type_name)) {\n    db.execute(installReq);\n}","handlingStrategy":"validation","validationCode":"List<String> existing = db.getDatabaseInformation().execats;\nboolean already = existing != null && existing.contains(req.type_name);\nif (!already) db.execute(req);","typeGuard":null,"tryCatchPattern":"catch (LSHException e) { if (e.getMessage().contains(\"already exists\")) { /* harmless on re-run, skip */ } else throw e; }","preventionTips":["Pre-check existing categories before installing to make scripts idempotent.","Treat 'already exists' as a benign condition in re-runnable automation."],"tags":["bsim","state","idempotency"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}