{"record":{"id":"ce2f574102270035","repo":"NationalSecurityAgency/ghidra","slug":"function-tag-already-exists","errorCode":null,"errorMessage":"Function tag already exists","messagePattern":"Function tag 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":2232,"sourceCode":"\tpublic List<String> getFunctionTags() {\n\t\treturn info.functionTags;\n\t}\n\n\t/**\n\t * Entry point for the InstallTagRequest command\n\t * @param query the install query to execute\n\t * @throws LSHException if the function tag already exists or is not valid\n\t * @throws SQLException if there is an error issuing the query\n\t */\n\tprivate void fdbInstallTag(InstallTagRequest query) throws LSHException, SQLException {\n\t\tResponseInfo response = query.installresponse;\n\t\tif (!CategoryRecord.enforceTypeCharacters(query.tag_name)) {\n\t\t\tthrow new LSHException(\"Bad characters in proposed function tag\");\n\t\t}\n\t\t// Check for existing tag\n\t\tif (info.functionTags != null) {\n\t\t\tif (info.functionTags.contains(query.tag_name)) {\n\t\t\t\tthrow new LSHException(\"Function tag already exists\");\n\t\t\t}\n\t\t}\n\t\tif (info.functionTags == null) {\n\t\t\tinfo.functionTags = new ArrayList<>();\n\t\t}\n\t\t// There are only 32-bits of space in the function record reserved for storing the presence of tags\n\t\tif (info.functionTags.size() >= FunctionTagBSimFilterType.MAX_TAG_COUNT) {\n\t\t\tthrow new LSHException(\n\t\t\t\t\"Cannot allocate new function tag: \" + query.tag_name + \" - Column space is full\");\n\t\t}\n\t\tinfo.functionTags.add(query.tag_name);\n\t\tkeyValueTable.writeFunctionTags(info);\n\t\tresponse.info = info;\n\t}\n\n\t/**\n\t * Entry point for the InstallMetadataRequest command\n\t * @param query the query to execute","sourceCodeStart":2214,"sourceCodeEnd":2250,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java#L2214-L2250","documentation":"Thrown by fdbInstallTag when query.tag_name already exists in info.functionTags. BSim prevents duplicate tag allocation since each tag occupies a fixed bitmask bit; duplicates would be ambiguous.","triggerScenarios":"Issuing an InstallTagRequest for a tag_name already present in the database's loaded functionTags list; re-running tag setup scripts without checking.","commonSituations":"Re-running initialization scripts; concurrent clients racing to install the same tag; migration/import tooling that doesn't first query existing tags.","solutions":["Pre-check info.functionTags for the tag name and skip if present.","Make tag-installation code idempotent.","Fetch current tags via QueryInfo before attempting installation."],"exampleFix":"// before\ndb.execute(installTagReq); // may already exist\n// after\nif (info.functionTags == null || !info.functionTags.contains(req.tag_name)) {\n    db.execute(installTagReq);\n}","handlingStrategy":"validation","validationCode":"List<String> existing = db.getDatabaseInformation().functionTags;\nif (existing == null || !existing.contains(req.tag_name)) {\n    db.execute(req);\n}","typeGuard":null,"tryCatchPattern":"catch (LSHException e) { if (e.getMessage().contains(\"already exists\")) { /* benign on re-run */ } else throw e; }","preventionTips":["Pre-check existing tags before installing to keep scripts idempotent.","Use QueryInfo to refresh the tag list in long-running clients."],"tags":["bsim","state","idempotency"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}