apache/seatunnel · error · IllegalStateException

Handler not reset

Error message

Handler not reset

What it means

TableSchemaChangeEventHandler.apply() requires the handler to have been initialized with a TableSchema via reset(schema). The handle() method checks get() before applying a SchemaChangeEvent and throws IllegalStateException if the handler was never reset with a schema (or was reset to null after a previous event). This is an internal lifecycle guard: each event application clears state, so a stale/uninitialized handler cannot silently mis-apply changes.

Source

Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/table/schema/handler/TableSchemaChangeEventHandler.java:31

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.seatunnel.api.table.schema.handler;

import org.apache.seatunnel.api.table.catalog.TableSchema;
import org.apache.seatunnel.api.table.schema.event.SchemaChangeEvent;

public interface TableSchemaChangeEventHandler extends SchemaChangeEventHandler<TableSchema> {

    TableSchema get();

    TableSchemaChangeEventHandler reset(TableSchema schema);

    default TableSchema handle(SchemaChangeEvent event) {
        if (get() == null) {
            throw new IllegalStateException("Handler not reset");
        }

        try {
            return apply(event);
        } finally {
            reset(null);
            if (get() != null) {
                throw new IllegalStateException("Handler not reset");
            }
        }
    }

    TableSchema apply(SchemaChangeEvent event);
}

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Call handler.reset(currentTableSchema) before each handle(event) invocation
  2. Do not reuse the handler for a second event without resetting it with the updated schema returned from the previous handle() call
  3. Check your custom handler: if you overrode reset/get, ensure get() returns the schema set by reset(schema)
  4. Wrap handler lifecycle: obtain schema, reset, then handle, in one sequential block

Example fix

// before
TableSchema result = handler.handle(event);
TableSchema result2 = handler.handle(event2); // throws: handler reset to null
// after
TableSchema result = handler.handle(event);
handler.reset(result);
TableSchema result2 = handler.handle(event2);
Defensive patterns

Strategy: validation

Validate before calling

if (handler.get() == null) {
    handler.reset(currentTableSchema);
}
TableSchema result = handler.handle(event);

Try / catch

try {
    TableSchema result = handler.handle(event);
} catch (IllegalStateException e) {
    handler.reset(currentSchema);
    // retry once or fail the pipeline with context
}

Prevention

When it happens

Trigger: Calling handle(event) on a handler that was constructed but never had reset(schema) called, or calling handle(event) twice without re-initializing via reset(schema) in between (since handle() ends with reset(null)).

Common situations: CDC/schema-change pipelines where the handler is created once and reused across multiple events without re-binding the current schema; custom event handler implementations that forget to call reset(schema) before dispatching events.

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


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/2a090efc69f34305. Report an issue: GitHub.