skylot/jadx · warning · JadxRuntimeException

Usage info collection failed with error: {} at insn: {}

Error message

Usage info collection failed with error: {} at insn: {}

What it means

Thrown (and then re-caught one level up in UsageInfoVisitor.processMethod, where it becomes mth.addError) when per-instruction usage scanning raises any exception - typically a malformed instruction, an unresolvable type/field/method reference, or a NPE in processInsn. Because processMethod wraps processInstructions in its own try/catch that records the failure as a method-level error, the practical effect is a warning comment, not a fatal abort.

Source

Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/usage/UsageInfoVisitor.java:132

		} catch (Exception e) {
			mth.addError("Dependency scan failed", e);
		}
	}

	private static void processInstructions(MethodNode mth, UsageInfo usageInfo) {
		if (mth.isNoCode()) {
			return;
		}
		ICodeReader codeReader = mth.getCodeReader();
		if (codeReader == null) {
			return;
		}
		RootNode root = mth.root();
		codeReader.visitInstructions(insnData -> {
			try {
				processInsn(root, mth, insnData, usageInfo);
			} catch (Exception e) {
				throw new JadxRuntimeException(
						"Usage info collection failed with error: " + e.getMessage() + " at insn: " + insnData, e);
			}
		});
	}

	private static void processInsn(RootNode root, MethodNode mth, InsnData insnData, UsageInfo usageInfo) {
		if (insnData.getOpcode() == Opcode.UNKNOWN) {
			return;
		}
		switch (insnData.getIndexType()) {
			case TYPE_REF:
				insnData.decode();
				ArgType usedType = ArgType.parse(insnData.getIndexAsType());
				usageInfo.clsUse(mth, usedType);
				break;

			case FIELD_REF:
				insnData.decode();

View on GitHub (pinned to e738a26571)

Solutions

  1. Update jadx - new opcodes and reference formats are added each release.
  2. Inspect the reported insn offset in the failing method to identify the unsupported/malformed instruction and file an issue.
  3. No code change needed if you already use jadx normally; the error is recorded as a method warning and the run continues.
  4. When embedding jadx, surface mth.getErrors()/class warnings to the user instead of treating this throw as fatal.
Defensive patterns

Strategy: try-catch

Try / catch

// jadx already converts this to mth.addError() upstream;
// surface those errors instead of catching the throw:
for (JadxError err : cls.getErrors()) {
    if (err.msg().contains("Usage info collection failed")) { ... }
}

Prevention

When it happens

Trigger: Decompiling a class where one method's bytecode contains an instruction whose index/type/method-handle decoding fails (e.g. an unknown opcode that is not UNKNOWN, a malformed type descriptor, or a field/method ref that points outside the DEX). The lambda inside codeReader.visitInstructions catches Exception and rethrows as JadxRuntimeException.

Common situations: Packed/protected apps, DEX edited by hand, multi-dex merges that lost string/type tables, or newer opcodes not yet supported by the jadx version in use. Usually scoped to one method; the rest of the class still decompiles.

Related errors


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/5fbdc7441e2ea469. Report an issue: GitHub.