{"record":{"id":"f05ee95467780fe7","repo":"apache/iceberg","slug":"invalid-operator-event-type-event-getclass-get-f05ee9","errorCode":null,"errorMessage":"Invalid operator event type: <event.getClass().getCanonicalName()>","messagePattern":"Invalid operator event type: <event\\.getClass\\(\\)\\.getCanonicalName\\(\\)>","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/TriggerManagerCoordinator.java","lineNumber":48,"sourceCode":"  TriggerManagerCoordinator(String operatorName, Context context) {\n    super(operatorName, context);\n    LOG.info(\"Created TriggerManagerCoordinator: {}\", operatorName);\n  }\n\n  @Override\n  public void handleEventFromOperator(int subtask, int attemptNumber, OperatorEvent event) {\n    runInCoordinatorThread(\n        () -> {\n          LOG.debug(\n              \"Handling event from subtask {} (#{}) of {}: {}\",\n              subtask,\n              attemptNumber,\n              operatorName(),\n              event);\n          if (event instanceof LockRegisterEvent) {\n            registerLock((LockRegisterEvent) event);\n          } else {\n            throw new IllegalArgumentException(\n                \"Invalid operator event type: \" + event.getClass().getCanonicalName());\n          }\n        },\n        String.format(\n            Locale.ROOT,\n            \"handling operator event %s from subtask %d (#%d)\",\n            event.getClass(),\n            subtask,\n            attemptNumber));\n  }\n}\n","sourceCodeStart":30,"sourceCodeEnd":60,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/TriggerManagerCoordinator.java#L30-L60","documentation":"TriggerManagerCoordinator only accepts LockRegisterEvent operator events; any other OperatorEvent delivered to it throws an IllegalArgumentException with the event's class name. This guards the event protocol between trigger operators and their coordinator.","triggerScenarios":"Sending a LockReleaseEvent (or any non-LockRegisterEvent OperatorEvent) to the TriggerManagerCoordinator via handleEventFromOperator.","commonSituations":"Cross-wiring the maintenance flow: lock-release events (meant for LockRemoverCoordinator) routed to the trigger manager, custom events, or mismatched operator-to-coordinator wiring after refactoring.","solutions":["Route LockReleaseEvent to LockRemoverCoordinator and only LockRegisterEvent to TriggerManagerCoordinator.","Check that each operator's OperatorEventGateway belongs to the correct coordinating operator.","If adding new event types, extend the coordinator's instanceof handling first."],"exampleFix":"// before\ntriggerCoordinatorGateway.sendOperatorEvent(new LockReleaseEvent(taskId));\n// after\nlockRemoverGateway.sendOperatorEvent(new LockReleaseEvent(taskId));","handlingStrategy":"type-guard","validationCode":"if (!(event instanceof LockRegisterEvent)) { throw new IllegalStateException(\"TriggerManagerCoordinator expects LockRegisterEvent, got \" + event.getClass()); }","typeGuard":"if (event instanceof LockRegisterEvent register) { /* register lock */ }","tryCatchPattern":"try { coordinator.handleEventFromOperator(subtask, attempt, event); } catch (IllegalArgumentException e) { LOG.error(\"Wrong event type for trigger coordinator\", e); }","preventionTips":["Send lock events through the correct gateway per coordinator role","Document which event types each coordinator/operator accepts","Add instanceof checks before dispatching operator events in custom code"],"tags":["flink","operator-event","iceberg-maintenance"],"backgroundTag":"invalid-argument-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}