Tencent/APIJSON · error · IllegalArgumentException

join:value 中 value 的 key@ 中 key 值 ${on.getKey()} 不合法!必须满足英文单

Error message

join:value 中 value 的 key@ 中 key 值 ${on.getKey()} 不合法!必须满足英文单词变量名格式!

What it means

Join.On.setKeyAndType strips the join-type prefix from the ON originKey to obtain the bare key; that key must satisfy StringUtil.isName. This IllegalArgumentException fires when the resulting key is not a valid identifier — e.g. the originKey carried type markers or characters that do not reduce to a clean name.

Source

Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractParser.java:1859

				}

				//对引用的JSONObject添加条件
				Map<String, Object> targetObj;
				try {
					targetObj = JSON.get(request, targetTableKey);
				}
				catch (Exception e2) {
					throw new IllegalArgumentException(e.getKey() + ":'/targetTable/targetKey' 中路径对应的 '" + targetTableKey + "':value 中 value 类型不合法!必须是 {} 这种 Map<String, Object> 格式!" + e2.getMessage());
				}

				if (targetObj == null) {
					throw new IllegalArgumentException(e.getKey() + ":'/targetTable/targetKey' 中路径对应的对象 '" + targetTableKey + "':{} 不存在或值为 null !必须是 {} 这种 Map<String, Object> 格式!");
				}

				Join.On on = new Join.On();
				on.setKeyAndType(j.getJoinType(), j.getTable(), originKey);
				if (StringUtil.isName(on.getKey()) == false) {
					throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":value 中 value 的 key@ 中 key 值 " + on.getKey() + " 不合法!必须满足英文单词变量名格式!");
				}

				on.setOriginKey(originKey);
				on.setOriginValue((String) refEntry.getValue());
				on.setTargetTableKey(targetTableKey);
				on.setTargetTable(targetTable);
				on.setTargetAlias(targetAlias);
				on.setTargetKey(targetKey);

				onList.add(on);
			}

			j.setOnList(onList);

			joinList.add(j);
			//			onList.add(table + "." + key + " = " + targetTable + "." + targetKey); // ON User.id = Moment.userId

			// 保证和 SQLExcecutor 缓存的 Config 里 where 顺序一致,生成的 SQL 也就一致 <<<<<<<<<

View on GitHub (pinned to 5284052872)

Solutions

  1. Use a plain identifier for the ON key inside the joined table object: 'toId@': '/User/id'
  2. Do not embed combine operators or extra '@' characters in join ON keys

Example fix

// before
{ 'join': '@/Comment', 'Comment': { 'to@id@': '/User/id' } }
// after
{ 'join': '@/Comment', 'Comment': { 'toId@': '/User/id' } }
Defensive patterns

Strategy: validation

Validate before calling

const NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
function checkOnOriginKeys(req, joinValue) {
  const paths = typeof joinValue === 'string' ? [joinValue] : Object.keys(joinValue);
  for (const p of paths) {
    const rest = p.substring(p.indexOf('/') + 1);
    const tblKey = rest.includes('/') ? rest.substring(0, rest.lastIndexOf('/')) : rest;
    const tbl = req[tblKey.split(':')[0]];
    for (const k of Object.keys(tbl || {})) {
      if (k.endsWith('@') && !NAME_RE.test(k.slice(0, -1))) {
        return `ON key '${k}' in ${tblKey} reduces to an invalid identifier`;
      }
    }
  }
  return null;
}

Type guard

const isCleanOnKey = (k) => /^[A-Za-z_][A-Za-z0-9_]*@$/.test(k);

Try / catch

Catch IllegalArgumentException with 'key@ 中 key 值'; rename the ON key to a plain identifier.

Prevention

When it happens

Trigger: Origin keys like 'to@id@' (embedded '@'), 'key1|key2@' (combine-style operator inside), 'user id@' (space) on the joined table, after setKeyAndType leaves an invalid residue.

Common situations: Reusing @combine condition syntax ('|', '&') inside join ON keys; keys assembled from user input with punctuation; double '@' suffixes from template concatenation.

Related errors


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