{"record":{"id":"dd4bb83555d8d225","repo":"NationalSecurityAgency/ghidra","slug":"no-variant-codec-for-class","errorCode":null,"errorMessage":"No variant codec for class {}","messagePattern":"No variant codec for class (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/ProposedUtils/src/main/java/ghidra/util/database/DBCachedObjectStoreFactory.java","lineNumber":1016,"sourceCode":"\t\t\t\t\tSHORT_ARR, INT_ARR, LONG_ARR, STRING_ARR, ADDRESS, RANGE)\n\t\t\t\t.collect(Collectors.toMap(c -> c.getSelector(), c -> c));\n\t\tMap<Class<?>, PrimitiveCodec<?>> CODECS_BY_CLASS = CODECS_BY_SELECTOR.values()\n\t\t\t\t.stream()\n\t\t\t\t.collect(Collectors.toMap(c -> c.getValueClass(), c -> c));\n\n\t\t/**\n\t\t * Get the codec for the given type\n\t\t * \n\t\t * @param <T> the type\n\t\t * @param cls the class describing {@link T}\n\t\t * @return the codec\n\t\t * @throws IllegalArgumentException if the type is not supported\n\t\t */\n\t\tstatic <T> PrimitiveCodec<T> getCodec(Class<T> cls) {\n\t\t\t@SuppressWarnings(\"unchecked\")\n\t\t\tPrimitiveCodec<T> obj = (PrimitiveCodec<T>) CODECS_BY_CLASS.get(cls);\n\t\t\tif (obj == null) {\n\t\t\t\tthrow new IllegalArgumentException(\"No variant codec for class \" + cls);\n\t\t\t}\n\t\t\treturn obj;\n\t\t}\n\n\t\t/**\n\t\t * Get the codec for the given selector\n\t\t * \n\t\t * @param sel the selector\n\t\t * @return the codec\n\t\t * @throws IllegalArgumentException if the selector is unknown\n\t\t */\n\t\tstatic PrimitiveCodec<?> getCodec(byte sel) {\n\t\t\tPrimitiveCodec<?> obj = CODECS_BY_SELECTOR.get(sel);\n\t\t\tif (obj == null) {\n\t\t\t\tthrow new IllegalArgumentException(\"No variant codec with selector \" + sel);\n\t\t\t}\n\t\t\treturn obj;\n\t\t}","sourceCodeStart":998,"sourceCodeEnd":1034,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/util/database/DBCachedObjectStoreFactory.java#L998-L1034","documentation":"Thrown (unchecked IllegalArgumentException) by PrimitiveCodec.getCodec(Class) when the given class has no registered variant codec. Variant fields (Object-typed) support a fixed set of primitive/Array/String/Address/RecRange types registered in CODECS_BY_CLASS (BOOL, BYTE, CHAR, SHORT, INT, LONG, STRING, the matching arrays, ADDRESS, RANGE — notably no float/double). Any other class is unsupported.","triggerScenarios":"Storing a value whose class isn't in the supported variant set into a variant (Object-typed) DB field — e.g. a Float/Double (explicitly unsupported, per the 'No floats?' comment), a custom object, or a BigInteger. getCodec is called to pick the encoder and finds none.","commonSituations":"Putting a float/double into a variant field; storing a custom/domain class instead of a primitive; storing a Long where the registry only has the primitive-backed wrapper; assuming arbitrary Object types are supported.","solutions":["Store only a supported variant type (boolean/byte/char/short/int/long, String, the matching arrays, Address, or RecRange). Convert other types before storage.","For float/double (deliberately unsupported), encode as a long via Float.floatToIntBits / Double.doubleToLongBits and store the long, or use a dedicated typed field.","For custom objects, serialize to a String or byte[] and store that, or define a proper annotated sub-store."],"exampleFix":"// before\nvariantField.set(myObject.getScore()); // Float -> \"No variant codec for class java.lang.Float\"\n\n// after: encode unsupported numeric types to a supported one\nvariantField.set(Float.floatToIntBits(myObject.getScore())); // stored as Integer","handlingStrategy":"validation","validationCode":"// Only store supported variant types\nSet<Class<?>> supported = Set.of(boolean.class, byte.class, char.class, short.class,\n    int.class, long.class, String.class, Address.class, RecRange.class /* + matching arrays */);\nif (!supported.contains(value.getClass())) {\n    // convert (e.g. float -> int bits, custom -> String/byte[]) before storing\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store only supported primitive/String/Array/Address/RecRange types in variant fields.","Encode float/double as int/long bits (they are deliberately unsupported).","Serialize custom objects to String or byte[] rather than storing them directly."],"tags":["database","codec","variant-field","unsupported-type","illegal-argument","unchecked-exception"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}