skylot/jadx · error · JadxArgsValidateException

'{}' is unknown for parameter {}, possible values are {}

Error message

'{}' is unknown for parameter {}, possible values are {}

What it means

Thrown by DebugController.checkType(ArgType, Object value) immediately before sending a new value to the device via SmaliDebugger.setValueSync. It enforces that the Java object supplied matches the declared ArgType exactly (INT->Integer, STRING->String, LONG->Long, FLOAT->Float, DOUBLE->Double, OBJECT->Long where the Long is an object id). A mismatch means the caller built an inconsistent (type, value) pair, which would corrupt the JDWP write, so it is rejected up front.

Source

Thrown at jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java:977

		RenameConverter(String paramName) {
			this.paramName = paramName;
		}

		@Override
		public Set<RenameEnum> convert(String value) {
			if (value.equalsIgnoreCase("NONE")) {
				return EnumSet.noneOf(RenameEnum.class);
			}
			if (value.equalsIgnoreCase("ALL")) {
				return EnumSet.allOf(RenameEnum.class);
			}
			Set<RenameEnum> set = EnumSet.noneOf(RenameEnum.class);
			for (String s : value.split(",")) {
				try {
					set.add(RenameEnum.valueOf(s.trim().toUpperCase(Locale.ROOT)));
				} catch (Exception e) {
					throw new JadxArgsValidateException(
							'\'' + s + "' is unknown for parameter " + paramName
									+ ", possible values are " + enumValuesString(RenameEnum.values()));
				}
			}
			return set;
		}
	}

	public static class CommentsLevelConverter extends BaseEnumConverter<CommentsLevel> {
		public CommentsLevelConverter() {
			super(CommentsLevel::valueOf, CommentsLevel::values);
		}
	}

	public static class UseKotlinMethodsForVarNamesConverter extends BaseEnumConverter<UseKotlinMethodsForVarNames> {
		public UseKotlinMethodsForVarNamesConverter() {
			super(UseKotlinMethodsForVarNames::valueOf, UseKotlinMethodsForVarNames::values);
		}

View on GitHub (pinned to e738a26571)

Solutions

  1. Ensure the value object is coerced to the exact Java type matching the ArgType before calling modifyValueInternal (Integer for INT, Long for LONG/OBJECT, Float for FLOAT, Double for DOUBLE, String for STRING).
  2. Validate the (type, value) pair in the edit dialog before dispatching the modify request.
  3. If extending the editor to new types, update checkType's predicate list in lockstep.
  4. Treat the exception as a bug report: log the ArgType and value class and fix the producer.

Example fix

// before
private void checkType(ArgType type, Object value) {
    if (!(type == ArgType.INT && value instanceof Integer)
            && !(type == ArgType.STRING && value instanceof String)
            /* ... */
            && !(type == ArgType.OBJECT && value instanceof Long)) {
        throw new JadxRuntimeException("Type must be one of int, long, float, double, String or Object.");
    }
}

// after (coerce the parsed value before this check)
Object coerced = coerceToType(parsedText, type); // returns Integer/Long/Float/Double/String as needed
checkType(type, coerced);
debugger.setValueSync(regNum, castType(type), coerced, threadId, frameId);
Defensive patterns

Strategy: type-guard

Validate before calling

// Coerce the user-entered value to the exact Java type for the ArgType before modifyValueInternal:
Object coerce(ArgType type, String text) {
    if (type == ArgType.INT)    return Integer.decode(text);
    if (type == ArgType.LONG)   return Long.decode(text);
    if (type == ArgType.FLOAT)  return Float.valueOf(text);
    if (type == ArgType.DOUBLE) return Double.valueOf(text);
    if (type == ArgType.STRING) return text;
    if (type == ArgType.OBJECT) return Long.decode(text); // object id
    throw new IllegalArgumentException("Unsupported edit type: " + type);
}

Type guard

static boolean valueMatchesType(ArgType type, Object value) {
    return (type == ArgType.INT && value instanceof Integer)
        || (type == ArgType.STRING && value instanceof String)
        || (type == ArgType.LONG && value instanceof Long)
        || (type == ArgType.FLOAT && value instanceof Float)
        || (type == ArgType.DOUBLE && value instanceof Double)
        || (type == ArgType.OBJECT && value instanceof Long);
}

Try / catch

try {
    checkType(type, value);
    modifyValueInternal(valNode, castType(type), value);
} catch (JadxRuntimeException e) {
    if (e.getMessage().startsWith("Type must be one of")) {
        LOG.warn("Rejected value {} for type {}", value == null ? null : value.getClass(), type);
        showError("Value does not match register type");
        return false;
    }
    throw e;
}

Prevention

When it happens

Trigger: modifyValueInternal(valNode, type, value) is invoked with a value whose Java class does not pair with the ArgType, e.g. passing an Integer for ArgType.LONG, a String for ArgType.OBJECT, or a Long for ArgType.DOUBLE. The check runs before the synchronous set so the device never receives a malformed value.

Common situations: UI passing a parsed number literal as Integer while the register is ArgType.LONG; passing a parsed hex object id as String instead of Long; changes to the value-edit dialog that lost type coercion. This is a programming precondition failure in the GUI/controller layer, not an environment issue.

Related errors


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