skylot/jadx · critical · JadxRuntimeException
A state of class {} has duplicated to produce a class of {}
Error message
A state of class {} has duplicated to produce a class of {} What it means
Thrown in DuplicatedTraverserStateFactory when duplicating a traverser state. The factory captures the base state's class, calls duplicate(), and verifies the duplicate is the same class. If duplicate() returns a different runtime class, the duplication contract is violated and the cast would be unsafe.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/factory/DuplicatedTraverserStateFactory.java:20
import jadx.core.dex.visitors.finaly.traverser.state.TraverserActivePathState;
import jadx.core.dex.visitors.finaly.traverser.state.TraverserState;
import jadx.core.utils.exceptions.JadxRuntimeException;
public final class DuplicatedTraverserStateFactory<T extends TraverserState> extends TraverserStateFactory<T> {
private final T baseState;
public DuplicatedTraverserStateFactory(T baseState) {
this.baseState = baseState;
}
@SuppressWarnings("unchecked")
@Override
public T generateInternalState(TraverserActivePathState state) {
Class<? extends T> baseStateClass = (Class<? extends T>) baseState.getClass();
TraverserState duplicated = baseState.duplicate(state);
if (!baseStateClass.isInstance(duplicated)) {
throw new JadxRuntimeException(
"A state of class " + baseState.getClass() + " has duplicated to produce a class of " + duplicated.getClass());
}
return baseStateClass.cast(duplicated);
}
}
View on GitHub (pinned to e738a26571)
Solutions
- Update jadx — this is a development-time contract violation that will be patched
- Report as a jadx issue with the class names from the error message
- This cannot be triggered or resolved by user input; it requires a source fix in the state class
Defensive patterns
Strategy: try-catch
Try / catch
try {
jadxDecompiler.load();
jadxDecompiler.save();
} catch (JadxRuntimeException e) {
if (e.getMessage().contains("duplicated to produce a class of")) {
LOG.error("Internal jadx traverser state duplication bug — update jadx", e);
for (ClassNode cls : jadxDecompiler.getClasses()) {
try {
jadxDecompiler.decompileClass(cls);
} catch (JadxRuntimeException ex) {
LOG.warn("Skipped: {}", cls.getFullName());
}
}
} else {
throw e;
}
} Prevention
- Update jadx — this is a state duplication contract violation that will be patched
- Report as a jadx issue with the class names from the error message
- Decompile classes individually to isolate and skip the problematic class
- Use an alternative decompiler as fallback for the affected class
When it happens
Trigger: baseState.duplicate(state) returns a TraverserState whose runtime class differs from baseState.getClass(). The duplicate method's contract requires returning the same concrete type.
Common situations: A TraverserState subclass whose duplicate() method incorrectly instantiates a parent or sibling class instead of its own type; a refactoring that changed the class hierarchy without updating duplicate() implementations. This is a jadx internal development bug, not input-driven.
Related errors
- A sealed class, AbstractBlockPathTraverserHandler, has an un
- A traverser handler which was not expected to change path st
- Unknown var type for: {}
- Invalid args count in insn: {}
- Unexpected InsnArg types: {} and {}
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/c60041eba7c2ca5b.
Report an issue: GitHub.