{"record":{"id":"18259354dae685c8","repo":"apache/pulsar","slug":"invalid-object-type-s-when-expecting-s","errorCode":null,"errorMessage":"Invalid object type '%s' when expecting '%s'","messagePattern":"Invalid object type '(.+?)' when expecting '(.+?)'","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/util/TypeCheckUtil.java","lineNumber":28,"sourceCode":" *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.apache.pulsar.client.util;\n\nimport lombok.experimental.UtilityClass;\n\n@UtilityClass\npublic class TypeCheckUtil {\n    @SuppressWarnings(\"unchecked\")\n    public static <T> T checkType(Object o, Class<T> clazz) {\n        if (!clazz.isInstance(o)) {\n            throw new RuntimeException(\n                    String.format(\"Invalid object type '%s' when expecting '%s'\",\n                            o.getClass().getName(), clazz.getName()));\n        }\n        return (T) o;\n    }\n}\n","sourceCodeStart":10,"sourceCodeEnd":35,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/util/TypeCheckUtil.java#L10-L35","documentation":"TypeCheckUtil.checkType performs a runtime instanceof check and, when the supplied object is not an instance of the expected class, throws a RuntimeException with 'Invalid object type X when expecting Y'. Pulsar uses it internally where schema/object types must line up (e.g. typed message builders or schema validation paths). The exception is unchecked and carries the actual vs. expected fully-qualified class names.","triggerScenarios":"Passing an object of the wrong Java type to a Pulsar API that internally calls TypeCheckUtil.checkType — e.g. supplying a value/message/schema object whose runtime class differs from the schema's expected class (Schema<Foo> but a Bar instance, or a generic JSON object where a POJO is expected).","commonSituations":"Schema/POJO mismatches after changing the message class (version drift between producer and consumer code); using Schema.AUTO/JSON with raw Maps or byte arrays instead of the typed class; generics erasure hiding the mismatch at compile time.","solutions":["Make the object you pass match the class the schema was built with (check Schema.of(...) / JSONSchema.of(Class) generic parameter).","Verify producer and consumer use the same message POJO/version — recompile against the updated schema class.","If types legitimately differ, convert/map the object to the expected type before the call.","Use a typed schema (Schema.AVRO(Foo.class)) instead of a generic one so generics catch mismatches at compile time."],"exampleFix":"// before\nSchema<String> schema = Schema.STRING;\nproducer.newMessage(schema).value(42).send(); // Invalid object type 'java.lang.Integer' when expecting 'java.lang.String'\n// after\nproducer.newMessage(schema).value(\"42\").send();","handlingStrategy":"type-guard","validationCode":"if (!(expectedClass.isInstance(value))) {\n    throw new IllegalArgumentException(\"Expected \" + expectedClass.getName() + \" but got \"\n        + (value == null ? \"null\" : value.getClass().getName()));\n}","typeGuard":"static <T> boolean isExpectedType(Object o, Class<T> clazz) {\n    return clazz.isInstance(o);\n}\n// usage: if (isExpectedType(obj, Foo.class)) { Foo foo = clazz.cast(obj); }","tryCatchPattern":"try {\n    producer.newMessage(schema).value(obj).send();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Invalid object type\")) {\n        throw new IllegalArgumentException(\"Message value does not match schema type\", e);\n    }\n    throw e;\n}","preventionTips":["Always create producers/consumers with the same typed class as the schema (Schema.AVRO(Foo.class)).","Enable compile-time generics: avoid raw Schema types and unchecked casts.","Keep producer and consumer message classes in sync (same version of the schema POJO).","Write a unit test that serializes a sample message with the configured schema before deploying."],"tags":["type-mismatch","schema","pulsar-client"],"backgroundTag":"type-mismatch","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}