{"record":{"id":"87592d6dff1a7934","repo":"jeecgboot/JeecgBoot","slug":"jobgroup-empty-87592d","errorCode":"jobgroup_empty","errorMessage":"jobgroup_empty","messagePattern":"jobgroup_empty","errorType":"exception","errorClass":"XxlJobException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/controller/JobLogController.java","lineNumber":74,"sourceCode":"\t@Resource\n\tpublic XxlJobLogMapper xxlJobLogMapper;\n    @Autowired\n    private XxlJobService xxlJobService;\n\n\t@RequestMapping\n\tpublic String index(HttpServletRequest request,\n\t\t\t\t\t\tModel model,\n\t\t\t\t\t\t@RequestParam(value = \"jobGroup\", required = false, defaultValue = \"0\") Integer jobGroup,\n\t\t\t\t\t\t@RequestParam(value = \"jobId\", required = false, defaultValue = \"0\") Integer jobId) {\n\n\t\t// 1、init JobGroupList\n\t\t// find all jobGroup\n\t\tList<XxlJobGroup> jobGroupListTotal =  xxlJobGroupMapper.findAll();\n\n\t\t// filter JobGroupList\n\t\tList<XxlJobGroup> jobGroupList = JobGroupPermissionUtil.filterJobGroupByPermission(request, jobGroupListTotal);\n\t\tif (CollectionTool.isEmpty(jobGroupList)) {\n\t\t\tthrow new XxlJobException(I18nUtil.getString(\"jobgroup_empty\"));\n\t\t}\n\t\tList<Integer> jobGroupIds = jobGroupList.stream().map(XxlJobGroup::getId).toList();\n\n\t\t// 2、check jobId\n\t\tif (jobId > 0) {\n\t\t\t// valid jobId\n\t\t\tXxlJobInfo jobInfo = xxlJobInfoMapper.loadById(jobId);\n\t\t\tif (jobInfo == null) {\n\t\t\t\tthrow new RuntimeException(I18nUtil.getString(\"jobinfo_field_id\") + I18nUtil.getString(\"system_invalid\"));\n\t\t\t}\n\t\t\t// valid jobGroup\n\t\t\tjobGroup = jobInfo.getJobGroup();\n\t\t}\n\n\t\t// 3、init jobGroup, default first 1\n\t\tif (!jobGroupIds.contains(jobGroup)) {\n\t\t\tjobGroup = jobGroupList.get(0).getId();\n\t\t}","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/controller/JobLogController.java#L56-L92","documentation":"Identical guard to error 271 but in JobLogController.index (the job log page). JobGroupPermissionUtil.filterJobGroupByPermission returns an empty list, meaning the current user has no authorized executor groups. Without any job group, there are no jobs to show logs for, so the page cannot render. Thrown as XxlJobException with i18n key 'jobgroup_empty'.","triggerScenarios":"User with no job group permissions navigates to the job execution log page. All executor groups were deleted. Permission configuration excludes all groups for this user's role or admin-level access.","commonSituations":"New operator who needs to view job logs but hasn't been assigned to any executor group. Audit or read-only accounts that were created without group permissions. Post-migration where executor groups were not recreated.","solutions":["Verify executor groups exist: SELECT id, app_name, title FROM xxl_job_group.","Grant the user access to at least one executor group via the XXL-Job admin permission management.","Check the JobGroupPermissionUtil filter logic — ensure the user's role/request headers correctly map to authorized groups.","If this is a fresh XXL-Job setup, create an executor group (Executor Management → Add) and register the executor."],"exampleFix":"// before: user navigates directly to log page without group access\nwindow.location.href = '/joblog';\n\n// after: verify group access first\nconst response = await api.get('/jobgroup/pageList');\nif (!response.data.data || response.data.data.length === 0) {\n  alert('No executor groups assigned. Please contact the administrator.');\n  return;\n}\nwindow.location.href = '/joblog';","handlingStrategy":"validation","validationCode":"// Check if user has any authorized job groups before loading the log page\npublic boolean hasAuthorizedJobGroups(HttpServletRequest request) {\n    List<XxlJobGroup> allGroups = xxlJobGroupMapper.findAll();\n    List<XxlJobGroup> filtered = JobGroupPermissionUtil.filterJobGroupByPermission(request, allGroups);\n    return !CollectionTool.isEmpty(filtered);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return \"business/job.log\";\n} catch (XxlJobException e) {\n    if (e.getMessage().contains(\"jobgroup_empty\")) {\n        model.addAttribute(\"error\", \"No executor groups assigned. Contact admin to assign permissions.\");\n        return \"business/job.log\";\n    }\n    throw e;\n}","preventionTips":["Grant executor group permissions to users who need to view job logs.","Ensure at least one executor group is registered and accessible to the user's role.","Check the permission-to-group mapping for new user accounts.","Create executor groups during initial XXL-Job setup."],"tags":["xxl-job","job-group","permissions","job-log","i18n"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}