{"record":{"id":"8532e2bae9212339","repo":"jwtk/jjwt","slug":"unsupported-value-type-expected-type-getname","errorCode":null,"errorMessage":"Unsupported value type. Expected: ${type.getName()}, found: ${clazz.getName()}","messagePattern":"Unsupported value type\\. Expected: (.+?), found: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/lang/RequiredTypeConverter.java","lineNumber":44,"sourceCode":"\n    public RequiredTypeConverter(Class<T> type) {\n        this.type = Assert.notNull(type, \"type argument cannot be null.\");\n    }\n\n    @Override\n    public Object applyTo(T t) {\n        return t;\n    }\n\n    @Override\n    public T applyFrom(Object o) {\n        if (o == null) {\n            return null;\n        }\n        Class<?> clazz = o.getClass();\n        if (!type.isAssignableFrom(clazz)) {\n            String msg = \"Unsupported value type. Expected: \" + type.getName() + \", found: \" + clazz.getName();\n            throw new IllegalArgumentException(msg);\n        }\n        return type.cast(o);\n    }\n}","sourceCodeStart":26,"sourceCodeEnd":48,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/lang/RequiredTypeConverter.java#L26-L48","documentation":"RequiredTypeConverter.applyFrom checks that a claim value's runtime class is assignable to the configured target type before calling type.cast(o). If not, it throws this IllegalArgumentException naming the expected and actual class names. Null values pass through and return null.","triggerScenarios":"Setting a claim value whose Java type does not match the converter's expected type, e.g. putting a String into a claim that must be a Date, or an Integer where a List is required.","commonSituations":"Copying claims from external JSON maps with loose typing; generic Map<String,Object> building where the wrong value slipped in; serialization round-trips that changed types (e.g. Date became String).","solutions":["Convert the value to the expected type before setting it (e.g. new Date(...) instead of an ISO string).","Check the class with type.isInstance(value) before assignment to fail fast.","Fix the source map/serialization so types survive round-trips correctly."],"exampleFix":"// before\njwtBuilder.claim(\"iat\", \"2026-09-08T12:00:00Z\"); // String, expected Date\n// after\njwtBuilder.claim(\"iat\", new Date());","handlingStrategy":"type-guard","validationCode":"void checkClaimType(Map<String,Object> claims, Class<?> type) {\n    for (Map.Entry<String,Object> e : claims.entrySet()) {\n        if (e.getValue() != null && !type.isInstance(e.getValue())\n                && !type.isAssignableFrom(e.getValue().getClass())) {\n            throw new IllegalArgumentException(\"Claim '\" + e.getKey() + \"' expected \" + type.getName());\n        }\n    }\n}","typeGuard":"<T> boolean isOfType(Object o, Class<T> type) {\n    return o == null || type.isInstance(o);\n}","tryCatchPattern":"try {\n    converter.applyFrom(value);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unsupported value type.\")) {\n        // parse the expected/found class names from the message to fix the value\n    }\n    throw e;\n}","preventionTips":["Use typed builders/setters instead of raw claim maps","Verify types after deserializing external JSON into claim maps","Enable strict typing at serialization boundaries so Dates stay Dates"],"tags":["type-mismatch","validation","claims"],"backgroundTag":"type-mismatch","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}