apache/dolphinscheduler · error · ServiceException

20016

20016

Error message

resource not exist or no permission,please view the task node and remove error resource

What it means

ServiceException(Status.RESOURCE_NOT_EXIST_OR_NO_PERMISSION, 20016) is thrown when the resource file IDs attached to the task definition fail the PermissionCheck (AuthorizationType.RESOURCE_FILE_ID) during an ONLINE release. Either a referenced resource no longer exists or the releasing user lacks permission on it.

Source

Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskDefinitionServiceImpl.java:375

                taskDefinition.setFlag(Flag.NO);
                taskDefinitionLog.setFlag(Flag.NO);
                break;
            case ONLINE:
                taskDatasourcePermissionChecker.checkPermission(loginUser,
                        Collections.singletonList(taskDefinitionLog));
                taskSubWorkflowPermissionChecker.checkPermission(loginUser,
                        Collections.singletonList(taskDefinitionLog));
                String resourceIds = taskDefinition.getResourceIds();
                if (StringUtils.isNotBlank(resourceIds)) {
                    Integer[] resourceIdArray =
                            Arrays.stream(resourceIds.split(",")).map(Integer::parseInt).toArray(Integer[]::new);
                    PermissionCheck<Integer> permissionCheck = new PermissionCheck(AuthorizationType.RESOURCE_FILE_ID,
                            processService, resourceIdArray, loginUser.getId(), log);
                    try {
                        permissionCheck.checkPermission();
                    } catch (Exception e) {
                        log.error("Resources permission check error, resourceIds:{}.", resourceIds, e);
                        throw new ServiceException(Status.RESOURCE_NOT_EXIST_OR_NO_PERMISSION);
                    }
                }
                taskDefinition.setFlag(Flag.YES);
                taskDefinitionLog.setFlag(Flag.YES);
                break;
            default:
                log.warn("Parameter releaseState is invalid.");
                throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR, Constants.RELEASE_STATE);
        }
        boolean updateSuccess = taskDefinitionDao.updateById(taskDefinition);
        int updateLog = taskDefinitionLogMapper.updateById(taskDefinitionLog);
        if (updateSuccess != (updateLog == 1)) {
            log.error("Update taskDefinition state or taskDefinitionLog state error, taskDefinitionCode:{}.", code);
            throw new ServiceException(Status.UPDATE_TASK_DEFINITION_ERROR);
        }
        log.info("Update taskDefinition state or taskDefinitionLog state to complete, taskDefinitionCode:{}.",
                code);
    }

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Open the task definition and remove/replace the stale resource references in the task node
  2. Re-upload the missing resource file and re-link it, ensuring the current user has access
  3. Grant loginUser permission on the referenced resource files, then retry the release
  4. Audit all task definitions for dangling resourceIds after resource cleanup

Example fix

// before: releasing with stale resourceIds
resourceIds: "10001,10002" // 10002 deleted
// after: remove the deleted id (or re-add the resource) before releasing
resourceIds: "10001"
Defensive patterns

Strategy: validation

Validate before calling

List<Integer> ids = Arrays.stream(resourceIds.split(",")).map(Integer::parseInt).collect(toList());
List<Resource> owned = resourceService.authorizedResourceFiles(loginUser.getId());
List<Integer> missing = ids.stream().filter(id -> owned.stream().noneMatch(r -> r.getId().equals(id))).collect(toList());
if (!missing.isEmpty()) throw new IllegalStateException("missing/unauthorized resources: " + missing);

Type guard

boolean allResourcesAuthorized(User user, List<Integer> resourceIds) {
    return resourceService.authorizedResourceFiles(user.getId()).stream()
        .map(Resource::getId).collect(toSet()).containsAll(resourceIds);
}

Try / catch

try {
    service.releaseTaskDefinition(loginUser, projectCode, code, ReleaseState.ONLINE);
} catch (ServiceException e) {
    if (e.getCode() == Status.RESOURCE_NOT_EXIST_OR_NO_PERMISSION.getCode()) { /* edit task node to drop stale resources */ }
    throw e;
}

Prevention

When it happens

Trigger: releaseTaskDefinition with releaseState=ONLINE where the task definition's resourceIds reference resource files that were deleted, moved, or are not owned/authorized for loginUser.getId().

Common situations: An admin deleted a shared resource file that workflow tasks still reference; user account changed (different tenant/permissions) since the task was authored; environment migration left resource IDs dangling.

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/7f168510008ecb97. Report an issue: GitHub.