Tencent/APIJSON · error · IllegalArgumentException

Value for key '" + key + "' is not a List: " +…

Error message

Value for key '" + key + "' is not a List: " + value.getClass().getName()

What it means

Thrown by apijson.JSON.getList(Map, String) (APIJSONORM/src/main/java/apijson/JSON.java:361) when the value at the given key is non-null but is not a java.util.List. APIJSON models JSON arrays as List and will not coerce a Map, String, or Number into one, so any structural mismatch fails fast with the key and the actual runtime class in the message.

Solutions

  1. Log the raw value and its class at that key to confirm what the sender actually produced.
  2. If a single object legitimately means a one-element list, normalize it before calling: wrap the Map in Collections.singletonList(map) or fix the producer to always emit an array.
  3. If the value is a delimited String, split it yourself: Arrays.asList(str.split(",")) instead of relying on getList.
  4. Check the key spelling against APIJSON array conventions (commonly the trailing "[]") — the object form often lives under the un-suffixed key.

Example fix

// before
List<Object> comments = JSON.getList(request, "Comment[]"); // throws when only one Map was sent

// after
Object raw = request.get("Comment[]");
List<Object> comments = raw instanceof List ? (List<Object>) raw
        : (raw instanceof Map ? Collections.singletonList(raw) : null);
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = request.get("Comment[]");
if (v != null && !(v instanceof List)) {
    throw new IllegalStateException("Expected JSON array for 'Comment[]', got " + v.getClass().getSimpleName());
}

Type guard

static boolean isJsonArray(Object v) {
    return v == null || v instanceof List;
}

Try / catch

try {
    List<Object> comments = JSON.getList(request, "Comment[]");
} catch (IllegalArgumentException e) {
    log.warn("'Comment[]' is not an array: {}", e.getMessage());
    // normalize single-object-to-list, or return 400 to the caller
}

Prevention

When it happens

Trigger: Calling JSON.getList(request, "Comment[]") or JSON.getList(response, "list") when the stored value is a single Map/JSONObject (sender sent one object instead of an array); the value is a comma-separated String like "1,2,3"; the value is a Number (e.g. a count) because the wrong key was used.

Common situations: REST endpoints that return an object when the collection has one item and an array otherwise; clients hand-building params and forgetting the [ ] wrapper APIJSON uses for array-valued request keys; switching the wrong key name (e.g. "Comment" vs "Comment[]"); serialized array strings from config that were never parsed.

Related errors


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

Appendix: source

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

	/**
	 * Get a List value from a Map
	 * @param map Source map
	 * @param key The key
	 * @return The List value
	 * @throws IllegalArgumentException If value is not a List and cannot be converted
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<T> getList(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 List) {
			return (List<T>) value;
		}

		throw new IllegalArgumentException("Value for key '" + key + "' is not a List: " + value.getClass().getName());
	}

	/**
	 * 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 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();
		}

View on GitHub (pinned to 5284052872)