Tencent/APIJSON · error · IllegalArgumentException
角色 {} 不存在!只能是[{}]中的一种!
Error message
角色 {} 不存在!只能是[{}]中的一种! What it means
Inside verifyAccess(), after the table is resolved, the role string taken from config.getRole() must exist in the static ROLE_MAP. ROLE_MAP holds the well-known APIJSON roles (ADMIN, OWNER, CONTACT, MEMBER, CIRCLE, UNKNOWN and friends); an unrecognized name throws IllegalArgumentException together with the list of legal names. This is a request-contract error: the client sent a role APIJSON cannot map.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java:277
public boolean verifyAccess(SQLConfig<T, M, L> config) throws Exception {
if (ENABLE_VERIFY_ROLE == false) {
throw new UnsupportedOperationException("AbstractVerifier.ENABLE_VERIFY_ROLE == false " +
"时不支持校验角色权限!如需支持则设置 AbstractVerifier.ENABLE_VERIFY_ROLE = true !");
}
String table = config == null ? null : config.getTable();
if (table == null) {
return true;
}
String role = config.getRole();
if (role == null) {
role = UNKNOWN;
}
else {
if (ROLE_MAP.containsKey(role) == false) {
Set<String> NAMES = ROLE_MAP.keySet();
throw new IllegalArgumentException("角色 " + role + " 不存在!" +
"只能是[" + StringUtil.get(NAMES.toArray()) + "]中的一种!");
}
if (role.equals(UNKNOWN) == false) { //未登录的角色
verifyLogin();
}
}
RequestMethod method = config.getMethod();
verifyRole(config, table, method, role);
return true;
}
@Override
public void verifyRole(SQLConfig<T, M, L> config, String table, RequestMethod method, String role) throws Exception {
verifyAllowRole(config, table, method, role); //验证允许的角色
verifyUseRole(config, table, method, role); //验证使用的角色View on GitHub (pinned to 5284052872)
Solutions
- Change the request to use one of the roles printed in the message (they come from ROLE_MAP.keySet(), e.g. ADMIN, OWNER, CONTACT, CIRCLE, MEMBER, UNKNOWN).
- Check for case/spelling typos in the "role" value in the request JSON — matching is exact and case-sensitive.
- If a custom role is genuinely needed, extend the verifier and populate ROLE_MAP (or override verifyAccess/verifyRole) in your subclass instead of sending an unregistered name.
- Omit the role key entirely to fall back to UNKNOWN/anonymous handling when that is the intent.
Example fix
// before
{
"User": { "id": 1 },
"role": "superuser",
"tag": "User"
}
// after
{
"User": { "id": 1 },
"role": "OWNER",
"tag": "User"
} Defensive patterns
Strategy: validation
Validate before calling
Set<String> allowed = AbstractVerifier.ROLE_MAP.keySet();
if (role != null && !allowed.contains(role)) {
throw new ClientError("role must be one of " + allowed + ", got " + role);
} Type guard
boolean isValidRole(String r) { return r == null || AbstractVerifier.ROLE_MAP.containsKey(r); } Try / catch
catch (IllegalArgumentException e) when message starts with "角色" -> map to HTTP 400 with the allowed-role list from ROLE_MAP.keySet().
Prevention
- Expose the role list from ROLE_MAP to clients via a metadata endpoint or generated constants.
- Never invent client-side role names; share an enum of roles across front-end and backend.
When it happens
Trigger: A request object carries "role":"SUPERUSER" (or a typo like "ownner", or a localized/empty-string role) and the request reaches verifyAccess; ROLE_MAP.containsKey(role) is false and the exception lists the allowed role names.
Common situations: Client and server disagree on the role vocabulary; front-end sends an application-specific role that was never registered; case mismatch ("owner" vs "OWNER"); migrating from an older APIJSON whose role list differed.
Related errors
- {}.id 类型错误,类型必须是 Long/String!
- {method}请求,请在 {name} 内传 {key}:{} !
- Cannot convert value of type " + value.getClass().getName()
- 字符 " + function + " 不合法!
- 字符 " + method + " 不合法!函数的名称 function 不能为空且必须符合方法命名规范!总体必须为 f
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/9983eb6d6e2f404c.
Report an issue: GitHub.