Tencent/APIJSON · error · ConflictException

PUT {}, {}/{} 必须为 JSONRequest {} !

Error message

PUT {}, {}/{} 必须为 JSONRequest {} !

What it means

When 'key+' targets a JSONObject-valued column, each element of the argument array is merged into the target via putAll, so every element must itself be a Map (JSONRequest {}). If an element is a non-null non-Map (String, number, etc.), ConflictException is thrown with the key and index, telling you the required form 'key+': [{'key': value, ...}].

Source

Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java:759

			targetArray = JSON.createJSONArray();
		}

		for (int i = 0; i < array.size(); i++) {
			Object obj = array.get(i);
			if (obj == null) {
				continue;
			}

			if (isAdd) {
				if (targetArray != null) {
					if (targetArray.contains(obj)) {
						throw new ConflictException("PUT " + path + ", " + key + "/" + i + " 已存在!");
					}
					targetArray.add(obj);
				} else {
					if (obj != null && obj instanceof Map == false) {
						throw new ConflictException("PUT " + path + ", " + key + "/" + i + " 必须为 JSONRequest {} !");
					}
					targetObj.putAll((Map) obj);
				}
			} else {
				if (targetArray != null) {
					if (targetArray.contains(obj) == false) {
						throw new NullPointerException("PUT " + path + ", " + key + "/" + i + " 不存在!");
					}
					targetArray.remove(obj);
				} else {
					if (obj instanceof String == false) {
						throw new ConflictException("PUT " + path + ", " + key + "/" + i + " 必须为 String 类型 !");
					}
					if (targetObj.containsKey(obj) == false) {
						throw new NullPointerException("PUT " + path + ", " + key + "/" + i + " 不存在!");
					}
					targetObj.remove(obj);
				}

View on GitHub (pinned to 5284052872)

Solutions

  1. Send object elements: "settings+": [{ "theme": "dark" }] when the column holds a JSONObject.
  2. Determine the column's JSON type first and shape the payload accordingly (array of strings for arrays, array of objects for objects).
  3. For plain key assignment into the object, a single-element array with one merge object is enough.

Example fix

// before (settings column is a JSON object)
{ "User": { "id": 1, "settings+": ["dark"] } }
// after
{ "User": { "id": 1, "settings+": [ { "theme": "dark" } ] } }
Defensive patterns

Strategy: type-guard

Validate before calling

Object current = fetchColumnValue(tableName, id, key);
boolean isObj = current instanceof Map;
for (Object o : payload) {
  if (isObj && !(o instanceof Map)) throw new IllegalArgumentException(key + "+ element must be a JSONRequest {} for object columns");
}

Type guard

function payloadMatchesColumnType(current: unknown, payload: unknown[]): boolean {
  const isObj = current !== null && typeof current === 'object' && !Array.isArray(current);
  return payload.every(p => isObj ? p !== null && typeof p === 'object' && !Array.isArray(p) : true);
}

Prevention

When it happens

Trigger: PUT { "settings+": ["dark"] } where settings is a JSON object column — the string element cannot be merged into an object. Same for numbers/booleans/arrays as elements.

Common situations: Using the same payload shape for object and array columns; switching a column from array to object without updating clients; docs examples copy-pasted across column types.

Related errors


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