{"record":{"id":"0a7febc9860eff36","repo":"jwtk/jjwt","slug":"values-must-be-either-string-or-type-getname","errorCode":null,"errorMessage":"Values must be either String or ${type.getName()} instances. Value type found: ${value.getClass().getName()}.","messagePattern":"Values must be either String or (.+?) instances\\. Value type found: (.+?)\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/lang/EncodedObjectConverter.java","lineNumber":46,"sourceCode":"    }\n\n    @Override\n    public Object applyTo(T t) {\n        Assert.notNull(t, \"Value argument cannot be null.\");\n        return converter.applyTo(t);\n    }\n\n    @Override\n    public T applyFrom(Object value) {\n        Assert.notNull(value, \"Value argument cannot be null.\");\n        if (type.isInstance(value)) {\n            return type.cast(value);\n        } else if (value instanceof CharSequence) {\n            return converter.applyFrom((CharSequence) value);\n        } else {\n            String msg = \"Values must be either String or \" + type.getName() +\n                    \" instances. Value type found: \" + value.getClass().getName() + \".\";\n            throw new IllegalArgumentException(msg);\n        }\n    }\n}\n","sourceCodeStart":28,"sourceCodeEnd":50,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/lang/EncodedObjectConverter.java#L28-L50","documentation":"EncodedObjectConverter.applyFrom converts a raw input value into the target encoded object type (e.g. TextCodec-decoded byte arrays). It accepts only the target type itself or a CharSequence (interpreted as its encoded String form); any other type throws IllegalArgumentException stating the accepted value types and the offending runtime type.","triggerScenarios":"Passing a byte[]-incompatible object (Integer, Map, JSONObject, null-wrapped boxed types) where a String or the target encoded object is expected, e.g. setting a key/secret/IV claim with a non-String, non-byte-array value.","commonSituations":"Reading claim values from a JSON library that yields JSONArray/JSONObject or Numbers instead of Strings; passing Base64-decoded byte[] where a Base64 String is expected (or vice versa); wrong claim type after a schema change.","solutions":["Convert the value to String (or the exact target type) before passing: String.valueOf(v) or Base64 encoder.","Ensure byte[] values are passed as byte[], and textual encodings as String - don't pass wrapper/container objects.","Normalize JSON-parsed values: coerce Numbers/containers to the expected textual form."],"exampleFix":"// before\nbyte[] key = converter.applyFrom(secretMap.get(\"k\")); // Integer\n// after\nObject v = secretMap.get(\"k\");\nbyte[] key = converter.applyFrom(v instanceof byte[] ? v : String.valueOf(v));","handlingStrategy":"type-guard","validationCode":"if (!(value instanceof CharSequence) && !(value instanceof byte[])) {\n    value = String.valueOf(value);\n}","typeGuard":"static boolean isEncodable(Object v) {\n    return v instanceof CharSequence || v instanceof byte[];\n}","tryCatchPattern":"try {\n    T obj = converter.applyFrom(value);\n} catch (IllegalArgumentException e) {\n    // convert value to String/target type and retry\n}","preventionTips":["Pass text encodings as String and raw data as byte[] - nothing else","Normalize JSON-parsed values (Numbers, containers) to strings first","Keep claim schemas stable between producers and consumers"],"tags":["type-mismatch","conversion","argument-validation"],"backgroundTag":"invalid-argument-value","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"}