skylot/jadx · error · JadxRuntimeException
Can't change package for inner class
Error message
Can't change package for inner class
What it means
Thrown by ClassInfo.changePkgAndName when the class is an inner class. Like error 92, this API refuses to repackage (or rename+repackage) an inner class because its identity is tied to its parent. The only difference from 92 is that this overload changes both package and short name together.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java:98
fillAliasFullName(newAlias);
}
this.alias = newAlias;
}
public void changePkg(String aliasPkg) {
if (isInner()) {
throw new JadxRuntimeException("Can't change package for inner class: " + this);
}
if (!Objects.equals(getAliasPkg(), aliasPkg)) {
ClassAliasInfo newAlias = new ClassAliasInfo(aliasPkg, getAliasShortName());
fillAliasFullName(newAlias);
this.alias = newAlias;
}
}
public void changePkgAndName(String aliasPkg, String aliasShortName) {
if (isInner()) {
throw new JadxRuntimeException("Can't change package for inner class");
}
ClassAliasInfo newAlias = new ClassAliasInfo(aliasPkg, aliasShortName);
fillAliasFullName(newAlias);
this.alias = newAlias;
}
private void fillAliasFullName(ClassAliasInfo alias) {
if (parentClass == null) {
alias.setFullName(makeFullClsName(alias.getPkg(), alias.getShortName(), null, true, false));
}
}
public String getAliasPkg() {
if (isInner()) {
return parentClass.getAliasPkg();
}
return alias == null ? getPackage() : alias.getPkg();
}View on GitHub (pinned to e738a26571)
Solutions
- Guard with isInner() before calling; route inner classes to their top-level parent for relocation.
- For inner classes that only need a rename (not a package change), use changeShortName instead, which is allowed for inner classes.
- In batch tools, separate the rename step (allowed for inner) from the repackage step (only top-level).
- Catch and skip inner classes in batch loops.
Example fix
// before
classInfo.changePkgAndName(newPkg, newName); // throws if inner
// after
if (classInfo.isInner()) {
classInfo.changeShortName(newName); // rename only, package inherited
} else {
classInfo.changePkgAndName(newPkg, newName);
} Defensive patterns
Strategy: validation
Validate before calling
if (classInfo.isInner()) {
classInfo.changeShortName(newName); // rename only
} else {
classInfo.changePkgAndName(newPkg, newName);
} Type guard
static boolean canChangePkgAndName(ClassInfo ci) {
return !ci.isInner();
} Try / catch
try {
classInfo.changePkgAndName(newPkg, newName);
} catch (JadxRuntimeException e) {
if (classInfo.isInner()) {
classInfo.changeShortName(newName);
} else {
throw e;
}
} Prevention
- Separate rename (allowed for inner) from repackage (top-level only).
- In batch tools, guard every changePkgAndName with isInner().
- Route inner classes to changeShortName when only a rename is needed.
When it happens
Trigger: Calling changePkgAndName(aliasPkg, aliasShortName) on a ClassInfo with isInner() == true. Batch rename tools that combine rename + move and do not filter inner classes.
Common situations: Same as 92: deobfuscation scripts, GUI rename-and-move on nested classes, refactors operating over the full class graph.
Related errors
- Can't change package for inner class: {}
- Class alias can't be empty
- Null class type
- Not class type: {}
- Package is null for not inner class
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/b11dd5c744830e38.
Report an issue: GitHub.