{"record":{"id":"c4159b7464b29273","repo":"apache/iceberg","slug":"invalid-operator-event-type-event-getclass-get","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/LockRemoverCoordinator.java","lineNumber":49,"sourceCode":"  LockRemoverCoordinator(String operatorName, Context context) {\n    super(operatorName, context);\n    LOG.info(\"Created LockRemoverCoordinator: {}\", 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 LockReleaseEvent) {\n            handleReleaseLock((LockReleaseEvent) 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":31,"sourceCodeEnd":61,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/LockRemoverCoordinator.java#L31-L61","documentation":"The Iceberg Flink maintenance LockRemoverCoordinator only accepts OperatorEvents that are instances of LockReleaseEvent. Any other OperatorEvent sent from a subtask to this coordinator is rejected with an IllegalArgumentException naming the unexpected event's canonical class name. This is an internal protocol guard: it means an event reached the wrong coordinator.","triggerScenarios":"Calling OperatorCoordinator.handleEventFromOperator with an OperatorEvent that is not a LockReleaseEvent (e.g. a LockRegisterEvent sent to the wrong coordinator, or a custom event).","commonSituations":"Wiring the TriggerManager's lock-register events into the maintenance job's LockRemover coordinator, mixing operator event types between the trigger and maintenance portions of the table maintenance flow, or custom code firing arbitrary OperatorEvents at the coordinator.","solutions":["Check which coordinator you are sending the event to; LockRegisterEvent must go to TriggerManagerCoordinator, LockReleaseEvent to LockRemoverCoordinator.","Verify the OperatorEventGateway used by your operator is obtained from the intended coordinator's context.","If you wrote a custom OperatorEvent, subclass LockReleaseEvent or register handling for it in the coordinator before sending."],"exampleFix":"// before\neventGateway.sendOperatorEvent(new LockRegisterEvent(lockFactory, lockId)); // sent to LockRemoverCoordinator\n// after\n// send register events to the TriggerManager coordinator, release events to the lock remover\ntriggerGateway.sendOperatorEvent(new LockRegisterEvent(lockFactory, lockId));","handlingStrategy":"type-guard","validationCode":"if (!(event instanceof LockReleaseEvent)) { throw new IllegalStateException(\"Wrong coordinator for event \" + event.getClass()); }","typeGuard":"if (event instanceof LockReleaseEvent release) { /* handle */ }","tryCatchPattern":"try { coordinator.handleEventFromOperator(subtask, attempt, event); } catch (IllegalArgumentException e) { LOG.error(\"Event routed to wrong coordinator\", e); }","preventionTips":["Keep two distinct gateways: one for trigger coordinator, one for the maintenance lock remover","Never send custom OperatorEvents to Iceberg's built-in coordinators","Review operator-to-coordinator wiring when refactoring the maintenance job"],"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"}