Tencent/APIJSON · error · IllegalArgumentException
请在最外层传 tag !一般是 Table 名,例如 "tag": "User"
Error message
请在最外层传 tag !一般是 Table 名,例如 "tag": "User"
What it means
buildTag() requires a top-level "tag" for non-CRUD operations when the object itself carries no tag. The tag (usually the table name) selects which request structure/permission template the verifier applies; without it verification cannot proceed.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractParser.java:2577
protected void setRequestAttribute(String key, boolean isArray, String attrKey, @NotNull Map<String, Object> request) {
Map<String, Object> attrMap = keyObjectAttributesMap.get(isArray ? key + KEY_ARRAY : key);
Object attrVal = attrMap == null ? null : attrMap.get(attrKey);
Map<String, Object> obj = attrVal == null ? null : JSON.get(request, key);
if (obj != null && obj.get(attrKey) == null) {
// 如果对象内部已经包含该属性,不覆盖
obj.put(attrKey, attrVal);
}
}
protected String buildTag(Map<String, Object> request, String key, RequestMethod method, String tag) {
if (method == RequestMethod.CRUD) {
Map<String, Object> attrMap = keyObjectAttributesMap.get(key);
Object _tag = attrMap == null ? null : attrMap.get(KEY_TAG);
return _tag != null ? _tag.toString() : StringUtil.isEmpty(tag) ? key : tag;
} else {
if (StringUtil.isEmpty(tag, true)) {
throw new IllegalArgumentException("请在最外层传 tag !一般是 Table 名,例如 \"tag\": \"User\" ");
}
}
return tag;
}
protected M objectVerify(RequestMethod method, String tag, int version, String name, @NotNull M request
, int maxUpdateCount, SQLCreator<T, M, L> creator, M object) throws Exception {
// 获取指定的JSON结构 >>>>>>>>>>>>>>
M target = wrapRequest(method, tag, object, true);
// Map<String, Object> clone 浅拷贝没用,Structure.parse 会导致 structure 里面被清空,第二次从缓存里取到的就是 {}
return getVerifier().setParser(this).verifyRequest(method, name, target, request, maxUpdateCount
, getGlobalDatabase(), getGlobalDatasource(), getGlobalNamespace(), getGlobalCatalog(), getGlobalSchema()
);
}
/***
* 兼容url crud, 获取真实methodView on GitHub (pinned to 5284052872)
Solutions
- Add a top-level tag equal to the table: {"tag": "User", "User": {...}}
- Or set a per-object tag via the method directive map: "@put": {"User": "User"}
- Centralize tag emission in the client's request builder so every write request carries it
Example fix
// before
POST /put {"User": {"id": 1, "name": "a"}}
// after
POST /put {"tag": "User", "User": {"id": 1, "name": "a"}} Defensive patterns
Strategy: validation
Validate before calling
if (method !== 'CRUD' && (req.tag == null || String(req.tag).trim() === '')) {
req.tag = Object.keys(req).find(k => !k.startsWith('@')) ?? null;
if (!req.tag) throw new Error('non-CRUD request needs a top-level tag, e.g. "tag":"User"');
} Type guard
const hasTag = req => typeof req?.tag === 'string' && req.tag.trim().length > 0;
Try / catch
try { await client.put(req); } catch (e) { if (e.message.includes('请在最外层传 tag')) { req.tag = deriveTagFromTable(req); return client.put(req); } throw e; } Prevention
- Request builder always injects tag = first non-@ key for write endpoints
- Document tag in the API contract for every non-CRUD endpoint
When it happens
Trigger: Calling /put, /delete or another non-CRUD batch endpoint with a body that has no "tag": "User" at the top level and no per-object tag provided via the method directive map.
Common situations: Migrating single-object requests to batch style and forgetting the tag; frontend builds the body from form data that never included tag; tag key removed during a refactor.
Related errors
- 不允许 tag = " + parser.getTag() + " 的请求调用远程函数 " + fb.getMethod
- ${key}: value 中 value 类型错误,只能是 String 或 Map<String, Object>
- ${key}: { ${objKey}: value 中 value 类型错误,只能是 String 或 Map<Str
- JSON 对象格式不正确 !正确示例例如 "User": {}
- {method} 请求,{name} 里面不允许 {rk}:[] 等未定义的 Table[]:[{}] 批量操作键值对!
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/2262b796109feed3.
Report an issue: GitHub.