Tencent/APIJSON · error · IllegalAccessException
没权限访问或对象不存在!
Error message
没权限访问或对象不存在!
What it means
Thrown as IllegalAccessException by AbstractSQLExecutor after a PUT/DELETE statement executes and updateCount <= 0. Zero affected rows means no row matched the WHERE conditions, which for writes is indistinguishable from 'no permission for that object' — so the request fails instead of returning success (the comment notes a NotExist-like success conversion must not happen here).
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java:242
//导致后面 rs.getMetaData() 报错 Operation not allowed after ResultSet closed result.put("moreResults", statement.getMoreResults());
}
else {
RequestMethod method = config.getMethod();
switch (method) {
case POST:
case PUT:
case DELETE:
if (isExplain == false) { //只有 SELECT 才能 EXPLAIN
executedSQLCount ++;
executedSQLStartTime = System.currentTimeMillis();
}
int updateCount = executeUpdate(config);
if (isExplain == false) {
executedSQLDuration += System.currentTimeMillis() - executedSQLStartTime;
}
if (updateCount <= 0) {
throw new IllegalAccessException("没权限访问或对象不存在!"); // NotExistException 会被 catch 转为成功状态
}
// updateCount>0时收集结果。例如更新操作成功时,返回count(affected rows)、id字段
result = parser.newSuccessResult(); // TODO 对 APIAuto 及其它现有的前端/客户端影响比较大,暂时还是返回 code 和 msg,5.0 再移除 JSON.createJSONObject();
//id,id{}至少一个会有,一定会返回,不用抛异常来阻止关联写操作时前面错误导致后面无条件执行!
result.put(JSONResponse.KEY_COUNT, updateCount);//返回修改的记录数
String idKey = config.getIdKey();
if (config.getId() != null) {
result.put(idKey, config.getId());
}
if (config.getIdIn() != null) {
result.put(idKey + "[]", config.getIdIn());
}
if (method == RequestMethod.PUT || method == RequestMethod.DELETE) {
config.setMethod(RequestMethod.GET);
View on GitHub (pinned to 5284052872)
Solutions
- Re-check that the target row exists (e.g. a prior GET with the same conditions/permissions) before retrying the write.
- Prefer addressing rows by primary key (id) rather than by mutable column values.
- Handle the 404-ish outcome in the client: treat as 'already deleted / no permission' and reconcile UI state instead of blindly retrying.
- If permission rules are the cause, adjust the request session/role or the access model for that table.
Example fix
// before
{"User": {"id": 123, "name": "old"}} // name already changed by someone else
// after
{"User": {"id": 123}} Defensive patterns
Strategy: try-catch
Validate before calling
const r = await apijson.get({ [table]: { id } });
if (!r[table] || Object.keys(r[table]).length === 0) throw new NotFoundError(`${table}#${id}`);
await apijson.put({ [table]: { id, ...changes } }); Try / catch
try {
await apijson.put(body);
} catch (e) {
if (e instanceof IllegalAccessException || /没权限访问或对象不存在/.test(e.message)) {
// row gone or not yours: reconcile UI, do not blind-retry
return { ok: false, reason: 'gone-or-forbidden' };
}
throw e;
} Prevention
- Address writes by primary key only.
- Handle double-submit (disable button while pending) to avoid racing deletes.
- Treat updateCount 0 as an expected outcome and surface it to the user.
When it happens
Trigger: PUT/DELETE where the id/condition matches nothing: record already deleted, wrong id, condition on a column value that changed, or row-level permission filtering that rewrites the WHERE to match nothing.
Common situations: Concurrent deletes (double submit), stale client data after another user's update, permission (visitor vs own data) rules excluding the row, or weak conditions like name-based matching.
Related errors
- 找不到 version: ${version}, method: ${method.name()}, tag: ${ta
- Value for key '" + key + "' is not a Map: " + value.getClass
- Value for key '" + key + "' is not a List: " + value.getClas
- Cannot convert String value '" + value + "' to int: " + e.ge
- Cannot convert value of type " + value.getClass().getName()
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/f535afe6e399e9f1.
Report an issue: GitHub.