jeecgboot/JeecgBoot · error · JeecgBootException
未找到菜单信息
Error message
未找到菜单信息
What it means
Thrown by SysPermissionServiceImpl.deletePermission (real/hard delete) when this.getById(id) returns null — the menu/permission to delete does not exist. This JeecgBootException prevents cascading deletes on a non-existent record. The method is transactional and evicts the data-permissions cache.
Source
Thrown at jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java:81
sysPermissionMapper.backupVue2Menu();
sysPermissionMapper.changeVue3Menu();
}
@Override
public List<TreeModel> queryListByParentId(String parentId) {
return sysPermissionMapper.queryListByParentId(parentId);
}
/**
* 真实删除
*/
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstant.SYS_DATA_PERMISSIONS_CACHE,allEntries=true)
public void deletePermission(String id) throws JeecgBootException {
SysPermission sysPermission = this.getById(id);
if(sysPermission==null) {
throw new JeecgBootException("未找到菜单信息");
}
String pid = sysPermission.getParentId();
if(oConvertUtils.isNotEmpty(pid)) {
Long count = this.count(new QueryWrapper<SysPermission>().lambda().eq(SysPermission::getParentId, pid));
if(count==1) {
//若父节点无其他子节点,则该父节点是叶子节点
this.sysPermissionMapper.setMenuLeaf(pid, 1);
}
}
sysPermissionMapper.deleteById(id);
// 该节点可能是子节点但也可能是其它节点的父节点,所以需要级联删除
this.removeChildrenBy(sysPermission.getId());
//关联删除
Map map = new HashMap(5);
map.put("permission_id",id);
//删除数据规则
this.deletePermRuleByPermId(id);
//删除角色授权表View on GitHub (pinned to 96fb33f5ec)
Solutions
- Add frontend debounce/loading state on the delete button to prevent duplicate requests.
- Refresh the menu/permission tree after a delete before attempting another.
- If calling programmatically, verify the permission exists before calling deletePermission.
- Consider catching JeecgBootException at the controller to return a friendly 'already deleted' message.
Example fix
// before
SysPermission sysPermission = this.getById(id);
if (sysPermission == null) {
throw new JeecgBootException("未找到菜单信息");
}
// after — controller handles gracefully
try {
permissionService.deletePermission(id);
} catch (JeecgBootException e) {
if (e.getMessage().contains("未找到")) {
return Result.OK("菜单已不存在,可能已被删除");
}
throw e;
} Defensive patterns
Strategy: validation
Validate before calling
// Validate permission exists before deleting
SysPermission perm = permissionService.getById(id);
if (perm == null) {
return Result.OK("菜单已不存在,可能已被删除");
}
permissionService.deletePermission(id); Type guard
public boolean isPermissionExists(String id) {
if (id == null || id.trim().isEmpty()) return false;
return permissionService.getById(id) != null;
} Try / catch
try {
permissionService.deletePermission(id);
} catch (JeecgBootException e) {
if (e.getMessage().contains("未找到菜单信息")) {
return Result.OK("菜单已不存在,可能已被删除");
}
throw e;
} Prevention
- Add loading state on delete buttons to prevent duplicate requests.
- Refresh the menu tree after deletion.
- Treat 'not found' on delete as idempotent success rather than an error.
When it happens
Trigger: Calling deletePermission with a permission ID that was already deleted (physically), doesn't exist, or is from a different tenant. The ID comes from the controller's delete endpoint.
Common situations: Double-click on a delete button causing two delete requests for the same menu; a menu was already hard-deleted by another admin; a stale menu ID from an outdated frontend menu tree.
Related errors
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/a4190bcc3c9a534d.
Report an issue: GitHub.