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.changePkg when attempting to change the package of a class that is an inner class (isInner() true). Package relocation is only valid for top-level classes; an inner class's package is derived from its parent, so changing it directly would break the parent/child relationship.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java:87
String aliasPkg = getAliasPkg();
if (Objects.equals(name, aliasName) || StringUtils.isEmpty(aliasName)) {
if (Objects.equals(getPackage(), aliasPkg)) {
newAlias = null;
} else {
newAlias = new ClassAliasInfo(aliasPkg, name);
}
} else {
newAlias = new ClassAliasInfo(aliasPkg, aliasName);
}
if (newAlias != null) {
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) {View on GitHub (pinned to e738a26571)
Solutions
- Check isInner() before calling changePkg; if true, relocate the enclosing top-level class instead (the inner follows its parent).
- For batch moves, iterate only top-level classes (parentClass == null) and let inner classes inherit.
- If you genuinely need to repackage an inner class, refactor it to a top-level class first (out of scope for this API).
- Catch JadxRuntimeException at the batch boundary to skip inner classes and continue.
Example fix
// before
classInfo.changePkg(newPkg); // throws if inner
// after
if (!classInfo.isInner()) {
classInfo.changePkg(newPkg);
} else {
// move the enclosing top-level class; inner follows
ClassInfo top = classInfo.getTopParentClass();
top.changePkg(newPkg);
} Defensive patterns
Strategy: validation
Validate before calling
if (classInfo.isInner()) {
// repackage the enclosing top-level class instead
classInfo.getTopParentClass().changePkg(newPkg);
} else {
classInfo.changePkg(newPkg);
} Type guard
static boolean isRepackageable(ClassInfo ci) {
return !ci.isInner();
} Try / catch
try {
classInfo.changePkg(newPkg);
} catch (JadxRuntimeException e) {
if (classInfo.isInner()) {
classInfo.getTopParentClass().changePkg(newPkg);
} else {
throw e;
}
} Prevention
- Filter to top-level classes before batch repackaging.
- Move the enclosing class so inner classes inherit the new package.
- Check isInner() before any package-change call.
When it happens
Trigger: Calling changePkg(aliasPkg) on a ClassInfo whose parentClass is non-null (an inner/nested class). Common in programmatic rename/batch-move operations that do not distinguish top-level from inner classes.
Common situations: Batch deobfuscation/rename scripts that move all classes to a new package; GUI 'move to package' invoked on an inner class; a refactor that reassigns packages recursively including nested classes.
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/bd7a58e99ddc3f3b.
Report an issue: GitHub.