LSPosed/LSPosed · error · IllegalArgumentException
${subClass} is not inherited from ${superClass}
Error message
${subClass} is not inherited from ${superClass} What it means
newInstanceSpecial allocates an instance of subClass and runs the superclass constructor on it via invokespecial. For that to be legal, subClass must actually inherit from the constructor's declaring class; LSPosedContext checks superClass.isAssignableFrom(subClass) (line 272) and throws IllegalArgumentException naming both classes otherwise.
Source
Thrown at core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java:272
throw new IllegalArgumentException("Cannot invoke special on static method: " + method);
}
return HookBridge.invokeSpecialMethod(method, getExecutableShorty(method), method.getDeclaringClass(), thisObject, args);
}
@NonNull
@Override
public <T> T newInstanceOrigin(@NonNull Constructor<T> constructor, Object... args) throws InvocationTargetException, IllegalAccessException, InstantiationException {
var obj = HookBridge.allocateObject(constructor.getDeclaringClass());
HookBridge.invokeOriginalMethod(constructor, obj, args);
return obj;
}
@NonNull
@Override
public <T, U> U newInstanceSpecial(@NonNull Constructor<T> constructor, @NonNull Class<U> subClass, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException, InstantiationException {
var superClass = constructor.getDeclaringClass();
if (!superClass.isAssignableFrom(subClass)) {
throw new IllegalArgumentException(subClass + " is not inherited from " + superClass);
}
var obj = HookBridge.allocateObject(subClass);
HookBridge.invokeSpecialMethod(constructor, getExecutableShorty(constructor), superClass, obj, args);
return obj;
}
@Override
public void log(@NonNull String message) {
Log.i(TAG, mPackageName + ": " + message);
}
@Override
public void log(@NonNull String message, @NonNull Throwable throwable) {
Log.e(TAG, mPackageName + ": " + message, throwable);
}
@Override
public DexParser parseDex(@NonNull ByteBuffer dexData, boolean includeAnnotations) throws IOException {View on GitHub (pinned to df74d83eb0)
Solutions
- Pass a class that genuinely extends constructor.getDeclaringClass()
- Derive the argument from the constructor itself if possible, or assert the relation before calling
- If you just want a normal instance of the declaring class, use newInstanceOrigin(constructor, args)
Example fix
// before Object o = context.newInstanceSpecial(BaseCtor, UnrelatedClass.class, args); // after assert BaseCtor.getDeclaringClass().isAssignableFrom(ChildClass.class); Object o = context.newInstanceSpecial(BaseCtor, ChildClass.class, args);
Defensive patterns
Strategy: validation
Validate before calling
Class<?> sup = constructor.getDeclaringClass();
if (!sup.isAssignableFrom(subClass)) {
throw new IllegalArgumentException(subClass + " must extend " + sup);
}
return context.newInstanceSpecial(constructor, subClass, args); Type guard
static boolean isValidSpecialTarget(Constructor<?> ctor, Class<?> sub) {
return ctor.getDeclaringClass().isAssignableFrom(sub);
} Prevention
- Assert isAssignableFrom before newInstanceSpecial
- Derive subClass from the same hierarchy as the constructor, or just use newInstanceOrigin for normal instantiation
When it happens
Trigger: Calling context.newInstanceSpecial(constructor, subClass, args) where subClass is not a subclass (or subinterface/array type) of constructor.getDeclaringClass().
Common situations: Passing an unrelated class or the declaring class itself when the constructor belongs to a different branch of the hierarchy; refactoring that moved the constructor's class so the old subClass argument no longer extends it.
Related errors
- Cannot hook abstract methods: ${hookMethod}
- Cannot hook Method.invoke
- Cannot deoptimize methods from proxy class: ${method}
- Cannot invoke special on static method: ${method}
- Do not allow hooking inner methods
AI-assisted analysis of LSPosed/LSPosed@df74d83eb0 (2026-08-14).
Data as JSON: /api/errors/0450f6b28145954a.
Report an issue: GitHub.