Tencent/APIJSON · error · IllegalArgumentException

Cannot convert value of type " + value.getClass().getName()

Error message

Cannot convert value of type " + value.getClass().getName() + " to int

What it means

Thrown by apijson.JSON.getInteger(Map, String) (APIJSONORM/src/main/java/apijson/JSON.java:389) when the value at the key is neither null, nor a Number, nor a String — the two accepted source types. Anything else (Boolean, Map, List, byte[]) is rejected with the value's runtime class name in the message.

Source

Thrown at APIJSONORM/src/main/java/apijson/JSON.java:389

	public static Integer getInteger(Map<String, Object> map, String key) throws IllegalArgumentException {
		Object value = map == null || key == null ? null : map.get(key);
		if (value == null) {
			return null;
		}

		if (value instanceof Number) {
			return ((Number) value).intValue();
		}

		if (value instanceof String) {
			try {
				return Integer.parseInt((String) value);
			} catch (NumberFormatException e) {
				throw new IllegalArgumentException("Cannot convert String value '" + value + "' to int: " + e.getMessage());
			}
		}

		throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to int");
	}

	/**
	 * Get an int value from a Map
	 * @param map Source map
	 * @param key The key
	 * @return The int value
	 * @throws IllegalArgumentException If value cannot be converted to int
	 */
	public static int getIntValue(Map<String, Object> map, String key) throws IllegalArgumentException {
		Object value = map == null || key == null ? null : map.get(key);
		if (value == null) {
			return 0;
		}

		if (value instanceof Number) {
			return ((Number) value).intValue();
		}

View on GitHub (pinned to 5284052872)

Solutions

  1. Log the class named in the message plus the raw value to identify what actually sits at that key.
  2. If the value is a container, extract the scalar you need explicitly (e.g. from the nested map) instead of pointing getInteger at the wrapper.
  3. Align the map contents with the JSON contract: only Number or numeric String may occupy this key — fix the producer or the test fixture.
  4. Guard the call with an instanceof check (Number || String) and apply your own fallback for other types.

Example fix

// before
int userId = JSON.getIntValue(req, "id"); // throws when "id" holds {"$": 123}

// after
Object raw = req.get("id");
if (raw instanceof Map) { raw = ((Map<?, ?>) raw).get("$"); }
int userId = raw instanceof Number ? ((Number) raw).intValue() : Integer.parseInt(String.valueOf(raw).trim());
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = req.get("id");
if (v != null && !(v instanceof Number) && !(v instanceof String)) {
    throw new IllegalStateException("'id' must be number or numeric string, got " + v.getClass().getName());
}

Type guard

static boolean isScalarNumberOrString(Object v) {
    return v == null || v instanceof Number || v instanceof String;
}

Try / catch

try {
    int id = JSON.getIntValue(req, "id");
} catch (IllegalArgumentException e) {
    log.warn("Non-scalar at 'id': {}", e.getMessage());
    // unwrap container if that is the real shape, else fail request with 400
}

Prevention

When it happens

Trigger: The field holds a JSON object or array (e.g. {"$": 1} wrapper or [1,2]) where a scalar was expected; the value is a Boolean; the map was populated from a non-JSON source that stored an Enum, Date, or byte[] under that key; a nested structure was flattened incorrectly so a container landed on a scalar field.

Common situations: API contract drift where a scalar field became structured (versioning change on the backend); reusing request maps as scratch storage and leaving a helper object under a numeric key; deserializers that map unknown JSON types into Map/List; unit tests hand-building maps with wrong literal types.

Related errors


AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14). Data as JSON: /api/errors/26dc597748220cc2. Report an issue: GitHub.