skylot/jadx · warning · JadxRuntimeException

Field handle not yet supported

Error message

Field handle not yet supported

What it means

In CustomRawCall.build(), the resolve bootstrap method handle (values[0]) is a field handle. CustomRawCall models invoke-custom as a polymorphic-style call and only supports method handles, so a field handle is explicitly unsupported.

Source

Thrown at jadx-core/src/main/java/jadx/core/dex/instructions/invokedynamic/CustomRawCall.java:38

import jadx.core.dex.nodes.RootNode;
import jadx.core.utils.exceptions.JadxRuntimeException;

import static jadx.core.utils.EncodedValueUtils.buildLookupArg;
import static jadx.core.utils.EncodedValueUtils.convertToInsnArg;

/**
 * Show `invoke-custom` similar to polymorphic call
 */
public class CustomRawCall {

	public static InsnNode build(MethodNode mth, InsnData insn, boolean isRange, List<EncodedValue> values) {
		IMethodHandle resolveHandle = (IMethodHandle) values.get(0).getValue();
		String invokeName = (String) values.get(1).getValue();
		IMethodProto invokeProto = (IMethodProto) values.get(2).getValue();
		List<InsnArg> resolveArgs = buildArgs(mth, values);

		if (resolveHandle.getType().isField()) {
			throw new JadxRuntimeException("Field handle not yet supported");
		}

		RootNode root = mth.root();
		MethodInfo resolveMth = MethodInfo.fromRef(root, resolveHandle.getMethodRef());
		InvokeType resolveInvokeType = InvokeCustomUtils.convertInvokeType(resolveHandle.getType());
		InvokeNode resolve = new InvokeNode(resolveMth, resolveInvokeType, resolveArgs.size());
		resolveArgs.forEach(resolve::addArg);

		ClassInfo invokeCls = ClassInfo.fromType(root, ArgType.OBJECT); // type will be known at runtime
		MethodInfo invokeMth = MethodInfo.fromMethodProto(root, invokeCls, invokeName, invokeProto);
		InvokeCustomRawNode customRawNode = new InvokeCustomRawNode(resolve, invokeMth, insn, isRange);
		customRawNode.setCallSiteValues(values);
		return customRawNode;
	}

	private static List<InsnArg> buildArgs(MethodNode mth, List<EncodedValue> values) {
		int valuesCount = values.size();
		List<InsnArg> list = new ArrayList<>(valuesCount);

View on GitHub (pinned to e738a26571)

Solutions

  1. Upgrade JADX.
  2. Check the issue tracker for field-handle invoke-custom support.
  3. Use --show-bad-code; the site degrades to a NOP with a JadxError.
  4. Report the bootstrap method handle type upstream.
Defensive patterns

Strategy: fallback

Type guard

// Detect a field-handle resolve bootstrap before calling CustomRawCall.build.
IMethodHandle resolveHandle = (IMethodHandle) values.get(0).getValue();
boolean unsupported = resolveHandle.getType().isField();

Try / catch

try {
    jadx.load();
} catch (JadxRuntimeException e) {
    if (e.getMessage().contains("Field handle not yet supported")) {
        log.warn("Field-handle invoke-custom not yet supported", e);
    } else throw e;
}

Prevention

When it happens

Trigger: An invoke-custom instruction whose bootstrap method handle is a field handle (STATIC_GET/PUT, INSTANCE_GET/PUT) rather than an invoke handle.

Common situations: Rare/novel bytecode patterns, custom bootstrap methods, or obfuscation. This is a known feature gap in the raw invoke-custom fallback path.

Related errors


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