{"record":{"id":"8d97aa74505adb48","repo":"apache/cassandra","slug":"event-class-must-be-of-type-diagnosticevent","errorCode":null,"errorMessage":"Event class must be of type DiagnosticEvent","messagePattern":"Event class must be of type DiagnosticEvent","errorType":"exception","errorClass":"InvalidClassException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/diag/DiagnosticEventPersistence.java","lineNumber":142,"sourceCode":"        Class<? extends DiagnosticEvent> cls = event.getClass();\n        logger.trace(\"Persisting received {} event\", cls.getName());\n        DiagnosticEventStore<Long> store = getStore(cls);\n        store.store(event);\n        LastEventIdBroadcaster.instance().setLastEventId(event.getClass().getName(), store.getLastEventId());\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private Class<DiagnosticEvent> getEventClass(String eventClazz) throws ClassNotFoundException, InvalidClassException\n    {\n        // get class by eventClazz argument name\n        // restrict class loading for security reasons\n        if (!eventClazz.startsWith(\"org.apache.cassandra.\"))\n            throw new RuntimeException(\"Not a Cassandra event class: \" + eventClazz);\n\n        Class<?> clazz = Class.forName(eventClazz, false, DiagnosticEventPersistence.class.getClassLoader());\n\n        if (!(DiagnosticEvent.class.isAssignableFrom(clazz)))\n            throw new InvalidClassException(\"Event class must be of type DiagnosticEvent\");\n\n        return (Class<DiagnosticEvent>) clazz.asSubclass(DiagnosticEvent.class);\n    }\n\n    private DiagnosticEventStore<Long> getStore(Class cls)\n    {\n        return stores.computeIfAbsent(cls, (storeKey) -> new DiagnosticEventMemoryStore());\n    }\n}\n","sourceCodeStart":124,"sourceCodeEnd":152,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/diag/DiagnosticEventPersistence.java#L124-L152","documentation":"After loading a Cassandra-namespaced class, getEventClass verifies it extends DiagnosticEvent. If not, it throws InvalidClassException(\"Event class must be of type DiagnosticEvent\") because diagnostic persistence can only store event objects deriving from DiagnosticEvent.","triggerScenarios":"Calling enableEventPersistence/getEvents/disableEventPersistence with an eventClazz that resolves to a Cassandra class but not a DiagnosticEvent subclass (e.g. passing a service or config class).","commonSituations":"Passing DiagnosticEventService or a management class instead of a concrete event class; renamed/refactored event hierarchy after upgrade; copy-paste of class names from unrelated packages.","solutions":["Pass a class that extends org.apache.cassandra.diag.DiagnosticEvent (see DiagnosticEventService registered events)","Check with javap or IDE that the target class inherits from DiagnosticEvent","Update the class name to the current one after Cassandra upgrades","Use org.apache.cassandra.diag.DiagnosticEventService.getEventClasses() equivalents to enumerate valid events"],"exampleFix":"// before\nbean.enableEventPersistence(\"org.apache.cassandra.diag.DiagnosticEventService\");\n// after\nbean.enableEventPersistence(\"org.apache.cassandra.diag.DiagnosticEvent\"); // must be a DiagnosticEvent subtype\nbean.enableEventPersistence(\"org.apache.cassandra.db.commitlog.CommitLogEvent\");","handlingStrategy":"type-guard","validationCode":"Class<?> c = Class.forName(name, false, loader);\nif (!DiagnosticEvent.class.isAssignableFrom(c))\n    throw new IllegalArgumentException(name + \" is not a DiagnosticEvent\");","typeGuard":"boolean isDiagnosticEvent(String name) {\n    try { return DiagnosticEvent.class.isAssignableFrom(Class.forName(name, false, loader)); }\n    catch (ClassNotFoundException e) { return false; }\n}","tryCatchPattern":"try {\n    bean.enableEventPersistence(eventClazz);\n} catch (InvalidClassException e) {\n    // resolve to a class extending org.apache.cassandra.diag.DiagnosticEvent\n}","preventionTips":["Only pass concrete event classes registered with DiagnosticEventService","Validate inheritance from DiagnosticEvent before enabling persistence","Track class renames across Cassandra upgrades"],"tags":["diagnostics","type-mismatch","class-loading"],"backgroundTag":"type-mismatch","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}