skylot/jadx · error · JadxRuntimeException
Incorrect negative register number in instruction: {}
Error message
Incorrect negative register number in instruction: {} What it means
Thrown by CheckCode.checkInstructions() when iterating every register referenced by an instruction and finding one whose register number is negative. Register numbers must be non-negative integers in valid Dalvik bytecode; a negative value indicates the instruction was built incorrectly during earlier decoding or that the DEX file is corrupt.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/CheckCode.java:76
if (isEmpty(mth.getInstructions())) {
return;
}
int regsCount = mth.getRegsCount();
List<RegisterArg> list = new ArrayList<>();
for (InsnNode insnNode : mth.getInstructions()) {
if (insnNode == null) {
continue;
}
list.clear();
RegisterArg resultArg = insnNode.getResult();
if (resultArg != null) {
list.add(resultArg);
}
insnNode.getRegisterArgs(list);
for (RegisterArg arg : list) {
int regNum = arg.getRegNum();
if (regNum < 0) {
throw new JadxRuntimeException("Incorrect negative register number in instruction: " + insnNode);
}
if (regNum >= regsCount) {
throw new JadxRuntimeException("Incorrect register number in instruction: " + insnNode
+ ", expected to be less than " + regsCount);
}
}
}
}
}
View on GitHub (pinned to e738a26571)
Solutions
- Upgrade jadx — instruction decoding and register handling are regularly fixed.
- Catch JadxRuntimeException around per-class decompilation to avoid aborting the whole batch.
- Report the issue with the instruction dump from the error message and the offending DEX.
- If the DEX is corrupt, re-verify with dexdump or baksmali and obtain a non-corrupt copy.
Defensive patterns
Strategy: try-catch
Validate before calling
// Basic DEX integrity sanity check before decompiling
import java.io.File;
import java.io.FileInputStream;
boolean looksLikeValidDex(File f) throws IOException {
try (FileInputStream fis = new FileInputStream(f)) {
byte[] magic = new byte[8];
if (fis.read(magic) < 8) return false;
// DEX magic: 'dex\n' followed by version and '\0'
return magic[0] == 'd' && magic[1] == 'e' && magic[2] == 'x' && magic[3] == '\n';
}
} Try / catch
try {
jadx.load();
jadx.save();
} catch (JadxRuntimeException e) {
// Catch at the batch level; consider per-class fallback
LOG.error("Decompilation failed (register validation): {}", e.getMessage());
} Prevention
- Validate input DEX files with dexdump --verify before decompiling.
- Use original APKs/DEX from trusted build tools; avoid re-processed or tampered files.
- Upgrade jadx for instruction-decoder fixes.
- Process per-class with try-catch to isolate corrupt methods.
When it happens
Trigger: CheckCode.visit() runs on a MethodNode, iterates mth.getInstructions(), collects result + source register args, and for some RegisterArg arg.getRegNum() < 0. This can happen if a register arg was created with an unset/default register number, or if a bytecode rewriter emitted an instruction with a malformed register operand.
Common situations: Corrupt or tampered DEX files, DEX produced by non-standard tools, or edge cases where jadx's own instruction decoder mis-parses a register slot. Rare with output from standard Android build tools (d8/r8).
Related errors
- Incorrect register number in instruction: {}, expected to be
- Bad name for type variable: {}
- Can't parse type: {}, unexpected: {}
- Invalid args count in insn: {}
- Null array element type
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/54812d1c804f3fc1.
Report an issue: GitHub.