{"record":{"id":"426b5dc27755a64a","repo":"FasterXML/jackson-databind","slug":"annotationintrospector-methodname-returned-va","errorCode":null,"errorMessage":"AnnotationIntrospector.${methodName}() returned value of type ${src.getClass().getName()}: expected type `ValueSerializer` or `Class<ValueSerializer>` instead","messagePattern":"AnnotationIntrospector\\.(.+?)\\(\\) returned value of type (.+?): expected type `ValueSerializer` or `Class<ValueSerializer>` instead","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/main/java/tools/jackson/databind/deser/DeserializerCache.java","lineNumber":576,"sourceCode":"            }\n            // Second: map(-like) types may have value handler for key (but not type; keys are untyped)\n            if (t.isMapLikeType()) {\n                JavaType kt = t.getKeyType();\n                if (kt.getValueHandler() != null) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    private Class<?> _verifyAsClass(Object src, String methodName, Class<?> noneClass)\n    {\n        if (src == null) {\n            return null;\n        }\n        if (!(src instanceof Class)) {\n            throw new IllegalStateException(\"AnnotationIntrospector.\"+methodName+\"() returned value of type \"\n+src.getClass().getName()+\": expected type `ValueSerializer` or `Class<ValueSerializer>` instead\");\n        }\n        Class<?> cls = (Class<?>) src;\n        if (cls == noneClass || ClassUtil.isBogusClass(cls)) {\n            return null;\n        }\n        return cls;\n    }\n\n    /*\n    /**********************************************************************\n    /* Error reporting methods\n    /**********************************************************************\n     */\n\n    protected ValueDeserializer<Object> _handleUnknownValueDeserializer(DeserializationContext ctxt, JavaType type)\n    {\n        // Let's try to figure out the reason, to give better error messages","sourceCodeStart":558,"sourceCodeEnd":594,"githubUrl":"https://github.com/FasterXML/jackson-databind/blob/87876ca5c0569b4933aec2d30d6225e4b9ba3a43/src/main/java/tools/jackson/databind/deser/DeserializerCache.java#L558-L594","documentation":"Thrown by DeserializerCache._verifyAsClass when an AnnotationIntrospector method (e.g. findSerializer, findKeySerializer, findContentSerializer) returns a non-null object that is not a Class. Despite living in DeserializerCache, the message text and the helper's usage target serializer definitions; the method is shared for verifying serializer definitions sourced from annotations.","triggerScenarios":"A custom AnnotationIntrospector override (findSerializer / findKeySerializer / findContentSerializer / findNullSerializer) returning an instance, a String, or any non-Class object instead of a Class<? extends ValueSerializer> or null.","commonSituations":"Returning an instantiated ValueSerializer from an introspector whose contract expects a Class; an introspector written against an older Jackson API; returning a Class object wrapped in another type (e.g. TypeReference).","solutions":["Return a Class<? extends ValueSerializer> or null from the introspector method named in the message.","If you must supply an instance, register it directly via a Module/SerializerFactory or ObjectMapper API rather than through the introspector.","Confirm you are on the Jackson 3.x introspector contract; 2.x returning patterns may differ."],"exampleFix":"// before\n@Override\npublic Object findSerializer(Annotated a) {\n    return new MySerializer(); // instance not allowed here\n}\n\n// after\n@Override\npublic Object findSerializer(Annotated a) {\n    return MySerializer.class; // Class<? extends ValueSerializer>\n}","handlingStrategy":"validation","validationCode":"Object v = introspector.findSerializer(annotated);\nif (v != null && !(v instanceof Class)) {\n    throw new IllegalStateException(\"findSerializer must return Class or null, got \" + v.getClass());\n}","typeGuard":"static boolean isSerializerClassDef(Object v) {\n    return v == null || (v instanceof Class<?> c && ValueSerializer.class.isAssignableFrom(c));\n}","tryCatchPattern":"try { mapper.writeValue(out, value); }\ncatch (IllegalStateException e) {\n    if (e.getMessage().contains(\"expected type `ValueSerializer` or `Class<ValueSerializer>`\")) {\n        // introspector returned a non-Class; return a Class<? extends ValueSerializer>\n    } else throw e;\n}","preventionTips":["Custom introspector find*Serializer methods return Class<? extends ValueSerializer> or null only.","For instances, register via Module or SerializerFactory instead of the introspector."],"tags":["serialization","annotation-introspector","configuration","custom-serializer"],"backgroundTag":null,"analyzedSha":"87876ca5c0569b4933aec2d30d6225e4b9ba3a43","analyzedAt":"2026-08-11T12:55:24.033Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}