{"record":{"id":"b12f44bb31d9e3b7","repo":"apache/dolphinscheduler","slug":"130018","errorCode":"130018","errorMessage":"The task group has been closed.","messagePattern":"The task group has been closed\\.","errorType":"error_code","errorClass":"ServiceException","httpStatus":null,"severity":"warning","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskGroupServiceImpl.java","lineNumber":214,"sourceCode":"    public PageInfo<TaskGroup> doQuery(User loginUser, int pageNo, int pageSize, int userId, String name,\n                                       Integer status) {\n        Page<TaskGroup> page = new Page<>(pageNo, pageSize);\n        IPage<TaskGroup> taskGroupPaging =\n                taskGroupMapper.queryTaskGroupPaging(page, name, status);\n\n        return buildPageInfo(pageNo, pageSize, taskGroupPaging);\n    }\n\n    @Override\n    public void closeTaskGroup(User loginUser, int id) {\n        if (!canOperatorPermissions(loginUser, null, AuthorizationType.TASK_GROUP,\n                ApiFuncIdentificationConstant.TASK_GROUP_CLOSE)) {\n            throw new ServiceException(Status.NO_CURRENT_OPERATING_PERMISSION);\n        }\n        TaskGroup taskGroup = taskGroupMapper.selectById(id);\n        if (taskGroup.getStatus() == Flag.NO) {\n            log.info(\"Task group has been closed, taskGroupId:{}.\", id);\n            throw new ServiceException(Status.TASK_GROUP_STATUS_CLOSED);\n        }\n        taskGroup.setStatus(Flag.NO);\n        if (taskGroupMapper.updateById(taskGroup) > 0) {\n            log.info(\"Task group close complete, taskGroupId:{}.\", id);\n        } else {\n            log.error(\"Task group close error, taskGroupId:{}.\", id);\n        }\n    }\n\n    @Override\n    public void startTaskGroup(User loginUser, int id) {\n        if (!canOperatorPermissions(loginUser, null, AuthorizationType.TASK_GROUP,\n                ApiFuncIdentificationConstant.TASK_GROUP_CLOSE)) {\n            throw new ServiceException(Status.NO_CURRENT_OPERATING_PERMISSION);\n        }\n        TaskGroup taskGroup = taskGroupMapper.selectById(id);\n        if (taskGroup.getStatus() == Flag.YES) {\n            log.info(\"Task group has been started, taskGroupId:{}.\", id);","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskGroupServiceImpl.java#L196-L232","documentation":"Thrown by closeTaskGroup when the target task group's status is already Flag.NO, i.e. it is already closed. This is an idempotency/state guard: closing an already-closed group is rejected with Status.TASK_GROUP_STATUS_CLOSED (code 130018).","triggerScenarios":"Calling POST /task-group/close twice on the same task group id; retrying a close request after a first attempt already succeeded; concurrent close calls from two clients.","commonSituations":"Double-clicked UI button; automated scripts re-running a close step after a timeout though the first call went through; UI state out of sync with the DB.","solutions":["Check the group status first via GET /task-group/list-paging and skip closing if already closed.","Treat code 130018 as success in idempotent retry logic (the desired end state is already reached).","Refresh the task group list in the UI before retrying.","If the group must be open, call /task-group/start first."],"exampleFix":"// before\ntry {\n    taskGroupService.closeTaskGroup(loginUser, id);\n} catch (ServiceException e) { /* retries blindly */ }\n// after\ntry {\n    taskGroupService.closeTaskGroup(loginUser, id);\n} catch (ServiceException e) {\n    if (e.getCode() != 130018) throw e; // already closed is acceptable\n}","handlingStrategy":"validation","validationCode":"// Java: check status before closing\nTaskGroup tg = taskGroupMapper.selectById(id);\nif (tg != null && tg.getStatus() == Flag.NO) {\n    return; // already closed, nothing to do\n}","typeGuard":"boolean isClosed(TaskGroup tg) {\n    return tg != null && tg.getStatus() == Flag.NO;\n}","tryCatchPattern":"try {\n    taskGroupService.closeTaskGroup(loginUser, id);\n} catch (ServiceException e) {\n    if (e.getCode() == 130018) {\n        log.info(\"Task group {} already closed; treating as success\", id);\n        return;\n    }\n    throw e;\n}","preventionTips":["Fetch current status before any close call.","Treat 'already closed' (130018) as success in retry/idempotent paths.","Debounce/double-submit protection on the close button in UIs.","Reconcile UI state with the DB after any failed request."],"tags":["task-group","idempotency","invalid-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}