{"record":{"id":"8f0d8c9a34203e19","repo":"apache/cassandra","slug":"exception-while-executing-trigger-on-table-with-id","errorCode":null,"errorMessage":"Exception while executing trigger on table with ID: %s","messagePattern":"Exception while executing trigger on table with ID: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/triggers/TriggerExecutor.java","lineNumber":281,"sourceCode":"                    cachedTriggers.put(td.classOption, trigger);\n                }\n                Collection<Mutation> temp = trigger.augment(update);\n                if (temp != null)\n                    tmutations.addAll(temp);\n            }\n            return tmutations;\n        }\n        catch (CassandraException ex)\n        {\n            throw ex;\n        }\n        catch (ClassNotFoundException ex)\n        {\n            throw new ConfigurationException(\"Trigger class \" + triggerClass + \" couldn't be found.\");\n        }\n        catch (Exception ex)\n        {\n            throw new RuntimeException(String.format(\"Exception while executing trigger on table with ID: %s\", update.metadata().id), ex);\n        }\n        finally\n        {\n            Thread.currentThread().setContextClassLoader(parent);\n        }\n    }\n\n    public synchronized Class<? extends ITrigger> loadTriggerClass(String triggerClass) throws Exception\n    {\n        // Allow loading the class regardless of Config, since this could happen as part of TCM replay via\n        // CreateTriggerStatement#apply.\n        // Check that triggerClass is available on the classpath, but do not initialize the class since that would\n        // execute static blocks.\n        Class<? extends ITrigger> trigger = loadTriggerClassWithoutInitialization(triggerClass);\n        // Validate that the class exposes a public no-argument constructor before it is accepted.\n        trigger.getConstructor();\n        return trigger;\n    }","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/triggers/TriggerExecutor.java#L263-L299","documentation":"Any exception other than ClassNotFoundException thrown while evaluating a trigger's ITrigger.augment (including instantiation and trigger execution failures) is wrapped in a RuntimeException carrying the table ID in this message, preserving the cause.","triggerScenarios":"A trigger's ITrigger.augment(Partition) throws (NPE, unsupported partition shape, internal error), or loadTriggerInstance throws TriggerDisabledException / reflective instantiation failures (no public no-arg constructor) during mutation execution.","commonSituations":"Custom trigger code buggy after a Cassandra upgrade; trigger class lacks a public no-argument constructor; trigger fails on specific partition data.","solutions":["Read the 'Caused by' exception in the log to find the root cause inside the trigger","Ensure the trigger class has a public no-arg constructor","Test the trigger's augment() against the failing partition locally","Fix or remove the trigger"],"exampleFix":"// before\npublic class MyTrigger implements ITrigger {\n    private MyTrigger() {}\n}\n// after\npublic class MyTrigger implements ITrigger {\n    public MyTrigger() {} // must be public no-arg\n}","handlingStrategy":"try-catch","validationCode":"// before deploying, ensure trigger has a public no-arg constructor\nClass<?> c = Class.forName(\"com.example.MyTrigger\");\nif (!java.lang.reflect.Modifier.isPublic(c.getDeclaredConstructor().getModifiers()))\n    throw new IllegalStateException(\"ITrigger must have a public no-arg constructor\");","typeGuard":null,"tryCatchPattern":"// inspect the cause chain of the wrapped RuntimeException from server logs\ntry {\n    session.execute(insert);\n} catch (RuntimeException e) {\n    Throwable root = e; while (root.getCause() != null) root = root.getCause();\n    log.error(\"Trigger failed: {}\", root);\n}","preventionTips":["Unit-test ITrigger.augment against representative partitions","Keep triggers simple and defensive (null-check partition contents)","Re-test triggers after every Cassandra upgrade","Avoid triggers for critical paths; prefer application-side augmentation"],"tags":["triggers","runtime-exception","custom-code"],"backgroundTag":"upstream-api-error","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"}