skylot/jadx · critical · JadxRuntimeException

A sealed class, AbstractBlockPathTraverserHandler, has an un

Error message

A sealed class, AbstractBlockPathTraverserHandler, has an unknown implementation

What it means

Thrown in the TraverserController's handler dispatch. The traverser framework uses a sealed class hierarchy with two known AbstractBlockTraverserHandler subclasses: AbstractBlockPathTraverserHandler and AbstractActivePathTraverserHandler. If a handler instance is neither, a new subclass was added without updating the dispatch logic.

Source

Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/TraverserController.java:45

 *
 * The terms "finally" and "candidate" are used to represent the two distinct subgraphs explored
 * by this controller; the "finally" subgraph, which is the subgraph which is what is being used
 * as a finally block, and the "candidate" subgraph, which is the subgraph which is being
 * compared to the "finally" subgraph to see if they are the same. There is only ever one
 * "finally" subgraph, however it is run against multiple different "candidate" subgraphs depending
 * on the complexity of the try catch block that this is being run for.
 */
public final class TraverserController {

	private static List<TraverserActivePathState> processHandlerImplementations(TraverserActivePathState state,
			AbstractBlockTraverserHandler handler) throws TraverserException {
		if (handler instanceof AbstractBlockPathTraverserHandler) {
			((AbstractBlockPathTraverserHandler) handler).process();
			return List.of(state);
		} else if (handler instanceof AbstractActivePathTraverserHandler) {
			return ((AbstractActivePathTraverserHandler) handler).process();
		} else {
			throw new JadxRuntimeException(
					"A sealed class, " + AbstractBlockPathTraverserHandler.class.getSimpleName() + ", has an unknown implementation");
		}
	}

	private final @Nullable Function<TraverserState, Boolean> stateAbortCondition;

	public TraverserController() {
		this(null);
	}

	public TraverserController(@Nullable Function<TraverserState, Boolean> stateAbortCondition) {
		this.stateAbortCondition = stateAbortCondition;
	}

	/**
	 * Processes a traverser path state using from a {@link TraverserActivePathState}. This
	 * function will continue evaluating an active path until either:
	 * <ul>

View on GitHub (pinned to e738a26571)

Solutions

  1. Update jadx — this will be fixed in the next release if it was a development regression
  2. Report as a jadx issue immediately — this is a sealed-class contract violation
  3. This cannot be triggered or fixed by user input; it requires a jadx source fix
Defensive patterns

Strategy: try-catch

Try / catch

try {
    jadxDecompiler.load();
    jadxDecompiler.save();
} catch (JadxRuntimeException e) {
    if (e.getMessage().contains("sealed class") && e.getMessage().contains("unknown implementation")) {
        LOG.error("Internal jadx traverser bug — update jadx and report this issue", e);
        // This is a development bug, switch to fallback or alternative decompiler
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: An AbstractBlockTraverserHandler subclass that is not one of the two known implementations is passed to processHandlerImplementations. The instanceof chain falls through to the else branch.

Common situations: This is a jadx internal development error, not input-driven. A developer added a new traverser handler subclass without updating the dispatch in TraverserController. Should never occur from any APK input.

Related errors


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/f85ba2ee98cbdf2b. Report an issue: GitHub.