skylot/jadx · error · CodegenException

Unknown arg type

Error message

Unknown arg type 

What it means

Thrown by InsnGen.addArg() when an InsnArg instance is not a register, not a literal, not an instruction wrapper, and not named. These four categories cover all expected arg subtypes; any other type means an unrecognized InsnArg subclass reached the code generator. This is an internal invariant violation.

Source

Thrown at jadx-core/src/main/java/jadx/core/codegen/InsnGen.java:125

	public void addArg(ICodeWriter code, InsnArg arg, boolean wrap) throws CodegenException {
		addArg(code, arg, wrap ? BODY_ONLY_FLAG : BODY_ONLY_NOWRAP_FLAGS);
	}

	public void addArg(ICodeWriter code, InsnArg arg, Set<Flags> flags) throws CodegenException {
		if (arg.isRegister()) {
			RegisterArg reg = (RegisterArg) arg;
			if (code.isMetadataSupported()) {
				code.attachAnnotation(VarNode.getRef(mth, reg));
			}
			code.add(mgen.getNameGen().useArg(reg));
		} else if (arg.isLiteral()) {
			addLiteralArg(code, (LiteralArg) arg, flags);
		} else if (arg.isInsnWrap()) {
			addWrappedArg(code, (InsnWrapArg) arg, flags);
		} else if (arg.isNamed()) {
			code.add(((Named) arg).getName());
		} else {
			throw new CodegenException("Unknown arg type " + arg);
		}
	}

	private void addLiteralArg(ICodeWriter code, LiteralArg litArg, Set<Flags> flags) {
		String literalStr = lit(litArg);
		if (!flags.contains(Flags.BODY_ONLY_NOWRAP) && literalStr.startsWith("-")) {
			code.add('(').add(literalStr).add(')');
		} else {
			code.add(literalStr);
		}
	}

	private void addWrappedArg(ICodeWriter code, InsnWrapArg arg, Set<Flags> flags) throws CodegenException {
		InsnNode wrapInsn = arg.getWrapInsn();
		if (wrapInsn.contains(AFlag.FORCE_ASSIGN_INLINE)) {
			code.add('(');
			makeInsn(wrapInsn, code, Flags.INLINE);
			code.add(')');

View on GitHub (pinned to e738a26571)

Solutions

  1. If you added a new InsnArg subtype, add a branch in addArg() or make it match one of the existing isXxx() checks.
  2. Report as an internal jadx bug with the full class and stack trace.
Defensive patterns

Strategy: type-guard

Type guard

// Type guard for InsnArg subtypes before code generation
private static boolean isKnownArgType(InsnArg arg) {
    return arg.isRegister() || arg.isLiteral()
        || arg.isInsnWrap() || arg.isNamed();
}
// Usage:
if (!isKnownArgType(arg)) {
    logger.warn("Unknown arg type, skipping: {}", arg.getClass());
    return;
}

Try / catch

try {
    insnGen.addArg(code, arg, flags);
} catch (CodegenException e) {
    if (e.getMessage().startsWith("Unknown arg type")) {
        code.add("/* unknown arg: " + arg + " */");
        logger.warn("Unknown instruction arg type", e);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: An InsnArg subclass that does not implement/override isRegister(), isLiteral(), isInsnWrap(), or isNamed() to return true. A new arg type added to jadx without updating addArg(). Internal state corruption where an arg loses its classification.

Common situations: Modifying jadx's instruction argument system and introducing a new arg type without updating InsnGen.addArg(). Rare in user-facing decompilation — typically a development-time issue.

Related errors


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