Konloch/bytecode-viewer · warning · UnexpectedException

Unknown opcode encountered:

Error message

Unknown opcode encountered: 

What it means

RegexInsnFinder.refresh builds an opcode-to-string lookup and throws an UnexpectedException when an instruction's opcode is >= 0 but outside the opcodes array bounds. This means the method's instruction list contains an opcode the finder's table does not cover, typically after an ASM version mismatch or corrupted/unusual bytecode. The exception is caught and routed to BytecodeViewer.handleException, so it surfaces as an error dialog rather than crashing.

Source

Thrown at src/main/java/the/bytecode/club/bytecodeviewer/searching/RegexInsnFinder.java:160

        for (AbstractInsnNode ain : mn.instructions.toArray())
            if (ain.getOpcode() >= 0)
            {
                il.add(ain);
            }
        AbstractInsnNode[] instructions = il.toArray(new AbstractInsnNode[0]);
        offsets = new int[instructions.length];
        StringBuilder insnStringBuilder = new StringBuilder();
        for (int i = 0; i < instructions.length; i++)
        {
            offsets[i] = -1;
            final AbstractInsnNode ain = instructions[i];
            if (ain.getOpcode() >= 0)
            {
                if (ain.getOpcode() >= opcodes.length)
                {
                    try
                    {
                        throw new UnexpectedException("Unknown opcode encountered: " + ain.getOpcode());
                    }
                    catch (UnexpectedException e)
                    {
                        BytecodeViewer.handleException(e);
                    }
                }
                offsets[i] = insnStringBuilder.length();
                insnStringBuilder.append(opcodes[ain.getOpcode()]);
                insnStringBuilder = new StringBuilder(getInsString(ain));
                insnStringBuilder.append(" ");
            }
        }
        insnString = insnStringBuilder.toString();
    }

    // Do a pattern check against each instruction directly,
    // without building a string of the whole method.
    public static boolean staticScan(ClassNode node, MethodNode mn, Pattern pattern)

View on GitHub (pinned to 31430e0033)

Solutions

  1. Update BCV/ASM so the opcode table covers all opcodes in the analyzed class
  2. Report the failing class to the BCV maintainers via handleException's dialog (this is flagged as an internal invariant break)
  3. Check the reported opcode value and confirm whether the input class file is corrupt or from an unsupported version
  4. Work around by excluding that class/method from regex instruction searching
Defensive patterns

Strategy: try-catch

Validate before calling

for (AbstractInsnNode ain : method.instructions) {
    int op = ain.getOpcode();
    if (op >= knownOpcodeCount) throw new IllegalStateException("Unsupported opcode " + op + " before regex search");
}

Try / catch

try {
    finder.setMethod(method);
} catch (UnexpectedException e) {
    BytecodeViewer.handleException(e); // or log opcode and skip this method
}

Prevention

When it happens

Trigger: Calling setMethod (which invokes refresh) on a MethodNode whose instructions contain an opcode >= opcodes.length — usually bytecode produced by a newer compiler/ASM version than the opcode table supports.

Common situations: Analyzing classes compiled with newer bytecode features after a library upgrade that changed opcode coverage; frameworks injecting exotic opcodes; a stale opcodes array after an ASM upgrade.

Related errors


AI-assisted analysis of Konloch/bytecode-viewer@31430e0033 (2026-09-05). Data as JSON: /api/errors/3d5b2749e7ccd700. Report an issue: GitHub.