Tencent/APIJSON · error · ConflictException

PUT {}, {}/{} 已存在!

Error message

PUT {}, {}/{} 已存在!

What it means

During 'key+': [...] processing on a JSONArray-valued column, each element to add is checked with targetArray.contains(obj); if the element is already present, a ConflictException is thrown identifying key and array index. This preserves set-like semantics for JSON array increments — duplicates are rejected rather than appended.

Source

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

						: " 类型为 " + target.getClass().getSimpleName() + ",不支持这样移除!")
						+ "对应字段在数据库的值必须为 JSONArray, JSONObject 中的一种,且 key- 移除时,本身的值不能为 null!"
						+ "值为 JSONRequest 类型时传参必须是 'key+': [{'key': value, 'key2': value2}] 或 'key-': ['key', 'key2'] !"
				);
			}

			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 类型 !");
					}

View on GitHub (pinned to 5284052872)

Solutions

  1. Client-side: diff against the current value and only send elements not yet present.
  2. Make PUT-with-key+ idempotent by catching ConflictException and treating 'already exists' as success when the retry is a duplicate submit.
  3. Guard against double submits in the UI/request layer.

Example fix

// before
put(new String[]{ "music" }); // tags already has "music" -> ConflictException
// after
List<String> add = currentTags.stream().filter(t -> !currentTags.contains(t)).collect(toList());
if (!add.isEmpty()) put(add.toArray(new String[0]));
Defensive patterns

Strategy: try-catch

Validate before calling

JSONArray current = fetchArrayColumn(tableName, id, key);
JSONArray toAdd = new JSONArray();
for (Object o : payload) if (!current.contains(o)) toAdd.add(o); // dedupe before sending
if (!toAdd.isEmpty()) sendKeyPlus(key, toAdd);

Type guard

function filterExisting<T>(current: T[], add: T[]): T[] {
  return add.filter(x => !current.some(c => JSON.stringify(c) === JSON.stringify(x)));
}

Try / catch

try { sendKeyPlus(...); } catch (ConflictException e) { if (e.getMessage().contains("已存在")) { /* duplicate submit: refetch and treat as success */ } else throw e; }

Prevention

When it happens

Trigger: PUT { "tags+": ["music"] } when the tags column already contains "music". Duplicate detection is exact equals on the parsed JSON value, so {"a":1} vs {"a":1} as equal Maps also conflicts.

Common situations: Retry of a previously successful PUT (idempotency mismatch); UI allowing double-submits; concurrent updates adding the same tag; number formatting differences (1 vs 1.0) making values look equal or not.

Related errors


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