NationalSecurityAgency/ghidra · error · LSHException

Bad category tag

Error message

Bad category tag

What it means

Thrown by CategoryRecord.restoreXml when parsing a <category> XML element whose type attribute or text content is null. The BSim category record XML format requires both a type attribute and a category value; a missing one means malformed XML, typically from a hand-edited or corrupted BSim metadata export.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/description/CategoryRecord.java:84

		if (arg0.category==null)
			return 1;		// this comes after null
		return category.compareTo(arg0.category);
	}

	public void saveXml(Writer fwrite) throws IOException {
		fwrite.append("  <category type=\"");
		fwrite.append(type);
		fwrite.append("\">");
		SpecXmlUtils.xmlEscapeWriter(fwrite, category);
		fwrite.append("</category>\n");		
	}
	
	public static CategoryRecord restoreXml(XmlPullParser parser) throws LSHException {
		XmlElement el = parser.start("category");
		String type = el.getAttribute("type");
		String category = parser.end().getText();
		if (type==null || category==null)
			throw new LSHException("Bad category tag");
		return new CategoryRecord(type,category);
	}
	
	public static boolean enforceTypeCharacters(String val) {
		if (val==null) return false;
		if (val.length()==0) return false;
		for(int i=0;i<val.length();++i) {
			char c = val.charAt(i);
			if (!Character.isLetterOrDigit(c)&&(c!=' ')&&(c!='.')&&(c!='_')&&(c!=':')&&(c!='/')&&(c!='(')&&(c!=')'))
				return false;
		}
		return true;
	}
}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Validate the category XML against the expected BSim schema before importing (each <category> must have a non-empty type attribute and text).
  2. Fix the malformed element in the source XML: add the missing type attribute or category text.
  3. Pre-scan the XML and skip/repair elements missing required fields.
  4. Regenerate the XML export from the original source if it is corrupted.

Example fix

// before (malformed XML):
// <category>somecategory</category>   <!-- missing type attribute -->

// after (well-formed):
// <category type="genre">somecategory</category>
Defensive patterns

Strategy: validation

Validate before calling

// Validate each <category> element has type and text before restore.
XmlElement el = parser.peek();
String type = el.getAttribute("type");
if (type == null || type.isEmpty()) {
    throw new IllegalArgumentException("<category> missing type attribute");
}

Try / catch

try {
    return CategoryRecord.restoreXml(parser);
} catch (LSHException e) {
    if (e.getMessage().contains("Bad category tag")) {
        parser.end(); // skip the malformed element
        return null; // or a default record
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling CategoryRecord.restoreXml(parser) on an XML stream where a <category> element lacks the type attribute (el.getAttribute("type") returns null) or has no text content (parser.end().getText() returns null). Occurs when importing/restoring a BSim category XML file that is malformed.

Common situations: Importing a BSim metadata XML file that was hand-edited and broke the schema. Corrupted XML export. A different tool/version producing category XML without the type attribute. Empty <category></category> elements.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/25ed088af7de65a8. Report an issue: GitHub.