skylot/jadx · error · UnsupportedOperationException
Centrality state is not supported for {}
Error message
Centrality state is not supported for {} What it means
Thrown as UnsupportedOperationException by TraverserState.getCentralityState() when getUnderlyingCentralityState() returns null. CentralityState tracks whether a traverser state allows central (merged) output and which output registers are permitted. Not all state types carry centrality — terminal states, global source states, and some cache-recovery states intentionally return null. Calling getCentralityState() on such a state is a programming error: the caller must check via the underlying accessor or ensure the state type supports centrality before calling.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserState.java:97
sb.append(secondIndent);
TraverserBlockInfo blockInsnInfo = getBlockInsnInfo();
if (blockInsnInfo != null) {
sb.append(blockInsnInfo.toString(secondIndent));
} else {
sb.append("NO ACTIVE BLOCK");
}
sb.append(System.lineSeparator());
sb.append(baseIndent);
sb.append("}");
return sb.toString();
}
public final CentralityState getCentralityState() {
CentralityState underlying = getUnderlyingCentralityState();
if (underlying == null) {
throw new UnsupportedOperationException("Centrality state is not supported for " + getClass().getName());
}
return underlying;
}
public final @Nullable TraverserBlockInfo getBlockInsnInfo() {
return getUnderlyingBlockInsnInfo();
}
public final GlobalTraverserSourceState getGlobalState() {
return getComparatorState().getGlobalStateFor(this);
}
}
View on GitHub (pinned to e738a26571)
Solutions
- Report to jadx developers with the input and stack trace.
- Workaround: disable the finally extraction pass.
- If developing jadx, call getUnderlyingCentralityState() (or the public getBlockInsnInfo()) first and skip centrality-dependent logic when null.
Example fix
// before
CentralityState cs = state.getCentralityState();
boolean allowsCentral = cs.getAllowsCentral();
// after
CentralityState cs = state.getUnderlyingCentralityState();
if (cs == null) {
return; // this state type does not support centrality
}
boolean allowsCentral = cs.getAllowsCentral(); Defensive patterns
Strategy: type-guard
Type guard
// Check for null centrality before calling getCentralityState()
CentralityState cs = state.getUnderlyingCentralityState();
if (cs == null) {
// This state type does not support centrality
return;
}
// Safe to use cs
boolean allowsCentral = cs.getAllowsCentral(); Prevention
- Always use getUnderlyingCentralityState() (nullable) instead of getCentralityState() (throws).
- When writing new finally-traverser code, test with inputs that produce terminal states early.
- Note that TraverserState.toString() already handles null safely — follow its pattern.
When it happens
Trigger: A visitor or handler calls state.getCentralityState() on a state subclass whose getUnderlyingCentralityState() returns null. This happens when code assumes all states have centrality but encounters a terminal or transitional state. Note that TraverserState.toString() safely checks for null before calling getCentralityState(), so only direct external callers are affected.
Common situations: New visitor or handler code added to the finally traverser that does not guard for null centrality. Typically surfaces during testing on edge-case inputs that produce terminal states early in traversal.
Related errors
- Null arg type in {} at: {} in: {}
- Expected to find block info within {}
- Orphaned traverser state
- Unknown global traverser state. Has a global state been dupl
- Orphaned traverser state
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/bb6b2df72b15fbb1.
Report an issue: GitHub.