apache/seatunnel · error · IllegalStateException
DataTypeChanger not reset
Error message
DataTypeChanger not reset
What it means
DataTypeChangeEventHandler.handle requires the handler to have been initialized with a data type via reset(SeaTunnelRowType) before processing events. If get() returns null, no data type was ever set, so applying a schema-change event that needs the current type fails immediately with IllegalStateException.
Source
Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/table/schema/handler/DataTypeChangeEventHandler.java:33
* limitations under the License.
*/
package org.apache.seatunnel.api.table.schema.handler;
import org.apache.seatunnel.api.table.schema.event.SchemaChangeEvent;
import org.apache.seatunnel.api.table.type.SeaTunnelRowType;
/** @deprecated instead by {@link TableSchemaChangeEventHandler} */
@Deprecated
public interface DataTypeChangeEventHandler extends SchemaChangeEventHandler<SeaTunnelRowType> {
SeaTunnelRowType get();
DataTypeChangeEventHandler reset(SeaTunnelRowType dataType);
default SeaTunnelRowType handle(SchemaChangeEvent event) {
if (get() == null) {
throw new IllegalStateException("DataTypeChanger not reset");
}
try {
return apply(event);
} finally {
reset(null);
if (get() != null) {
throw new IllegalStateException("DataTypeChanger not reset");
}
}
}
SeaTunnelRowType apply(SchemaChangeEvent event);
}
View on GitHub (pinned to cf67b549a7)
Solutions
- Call reset(currentSeaTunnelRowType) with the table's current row type before invoking handle(event).
- Ensure the handler is re-initialized after task restart/restore before consuming schema-change events.
- Guard the call site: only call handle when the handler has a non-null current type.
- Create a new handler instance per table/snapshot instead of sharing one.
Example fix
// before DataTypeChangeEventHandler h = new MyHandler(); SeaTunnelRowType t = h.handle(event); // IllegalStateException // after DataTypeChangeEventHandler h = new MyHandler().reset(currentRowType); SeaTunnelRowType t = h.handle(event);
Defensive patterns
Strategy: validation
Validate before calling
if (handler.get() == null) { handler.reset(currentRowType); } SeaTunnelRowType next = handler.handle(event); Type guard
boolean initialized = handler.get() != null;
Try / catch
try { return handler.handle(event); } catch (IllegalStateException e) { handler.reset(currentRowType); return handler.handle(event); } Prevention
- Always call reset(dataType) before handle()
- Re-initialize handlers after restore/restart
- Scope one handler instance per table snapshot
When it happens
Trigger: Calling handle(event) on a fresh/reset DataTypeChangeEventHandler without first calling reset(dataType) — e.g. reusing an event-handler instance across schema snapshots, or a connector forgetting to initialize the handler after obtaining it.
Common situations: Custom connector schema-evolution code constructing the handler and calling handle directly; handler instances recycled between CDC tasks without re-initialization after a checkpoint restore.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Unsupported alter table event:
- Unsupported alter table event:
- Handler not reset
- Multiple DebeziumAdapters matched connector class " + connec
- Invalid value for option '" + optionKey + "'. " + e.getMessa
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/f9b80217c2a8c6a2.
Report an issue: GitHub.