skylot/jadx · error · JadxRuntimeException

Unknown type in literalToString:

Error message

Unknown type in literalToString: 

What it means

Thrown by TypeGen.literalToString when converting a numeric literal to source text. The switch covers all ArgType primitive kinds (BOOLEAN, CHAR, BYTE, SHORT, INT, LONG, FLOAT, DOUBLE, OBJECT, ARRAY); the default branch fires only when the ArgType's primitive kind is null or an unrecognised value. Effectively an internal type-system invariant failure.

Solutions

  1. Run the latest jadx release.
  2. Log type and type.getPrimitiveType() at the throw site to identify which ArgType is invalid.
  3. Trace upstream: find which instruction/arg supplied the literal and fix type inference there instead of at the throw site.
  4. Submit a minimal reproducer to jadx.
  5. Workaround: decompile the offending class in fallback/no-debug mode or exclude it.

Example fix

// before
default:
    throw new JadxRuntimeException("Unknown type in literalToString: " + type);

// after (graceful fallback for null/unknown primitive)
default:
    LOG.warn("Unknown type in literalToString: {}", type);
    return Long.toString(lit);
Defensive patterns

Strategy: validation

Validate before calling

ArgType type = arg.getType();
if (type == null || type.getPrimitiveType() == null) {
    LOG.warn("Refusing literalToString on null/unknown type: {}", type);
    return Long.toString(arg.getLiteral());
}

Type guard

static boolean hasKnownPrimitive(ArgType t) {
    return t != null && t.getPrimitiveType() != null;
}

Try / catch

try {
    return TypeGen.literalToString(lit, type, mth, fallback);
} catch (JadxRuntimeException e) {
    LOG.warn("literalToString failed for type {}: {}", type, e.getMessage());
    return Long.toString(lit);
}

Prevention

When it happens

Trigger: An ArgType with a null or unknown PrimitiveType is passed to literalToString, e.g. a VOID literal, an ArgType.UNKNOWN, or a type whose getPrimitiveType() returns null (some non-primitive, non-object constructs). Reachable during codegen for any constant/emitted literal.

Common situations: Malformed bytecode where a constant instruction has a missing/unknown type; intermediate type-inference producing ArgType.UNKNOWN; version skew between jadx passes; very obfuscated inputs.

Related errors


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

Appendix: source

Thrown at jadx-core/src/main/java/jadx/core/codegen/TypeGen.java:103

			case INT:
				return stringUtils.formatInteger(lit, cast);
			case LONG:
				return stringUtils.formatLong(lit, cast);
			case FLOAT:
				return StringUtils.formatFloat(Float.intBitsToFloat((int) lit));
			case DOUBLE:
				return StringUtils.formatDouble(Double.longBitsToDouble(lit));

			case OBJECT:
			case ARRAY:
				if (lit != 0) {
					LOG.warn("Wrong object literal: {} for type: {}", lit, type);
					return Long.toString(lit);
				}
				return "null";

			default:
				throw new JadxRuntimeException("Unknown type in literalToString: " + type);
		}
	}

	@Nullable
	public static String literalToRawString(LiteralArg arg) {
		ArgType type = arg.getType();
		if (type == null) {
			return null;
		}
		long lit = arg.getLiteral();
		switch (type.getPrimitiveType()) {
			case BOOLEAN:
				return lit == 0 ? "false" : "true";
			case CHAR:
				return String.valueOf((char) lit);

			case BYTE:
			case SHORT:

View on GitHub (pinned to e738a26571)