flowable/flowable-engine · error · FlowableIllegalArgumentException

userId and groupId cannot both be null

Error message

userId and groupId cannot both be null

What it means

DeleteIdentityLinkForCaseDefinitionCmd.validateParams throws FlowableIllegalArgumentException when both userId and groupId are null. Even with a valid caseDefinitionId, at least one identity must be given to select the link row to delete.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/DeleteIdentityLinkForCaseDefinitionCmd.java:54

    protected String userId;

    protected String groupId;

    public DeleteIdentityLinkForCaseDefinitionCmd(String caseDefinitionId, String userId, String groupId) {
        validateParams(userId, groupId, caseDefinitionId);
        this.caseDefinitionId = caseDefinitionId;
        this.userId = userId;
        this.groupId = groupId;
    }

    protected void validateParams(String userId, String groupId, String caseDefinitionId) {
        if (caseDefinitionId == null) {
            throw new FlowableIllegalArgumentException("caseDefinitionId is null");
        }

        if (userId == null && groupId == null) {
            throw new FlowableIllegalArgumentException("userId and groupId cannot both be null");
        }
    }

    @Override
    public Void execute(CommandContext commandContext) {
        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
        CaseDefinitionEntity caseDefinition = cmmnEngineConfiguration.getCaseDefinitionEntityManager().findById(caseDefinitionId);

        if (caseDefinition == null) {
            throw new FlowableObjectNotFoundException("Cannot find case definition with id " + caseDefinitionId, CaseDefinition.class);
        }

        cmmnEngineConfiguration.getIdentityLinkServiceConfiguration().getIdentityLinkService()
            .deleteScopeDefinitionIdentityLink(caseDefinition.getId(), ScopeTypes.CMMN, userId, groupId);

        return null;
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Supply the userId or groupId that was originally added via addUserIdentityLink/addGroupIdentityLinkForCaseDefinition.
  2. Validate that exactly one identity is set before calling the API.

Example fix

// before
repositoryService.deleteUserIdentityLinkForCaseDefinition(defId, null, null);
// after
if (userId == null && groupId == null) throw new IllegalArgumentException("userId or groupId required");
repositoryService.deleteUserIdentityLinkForCaseDefinition(defId, userId, groupId);
Defensive patterns

Strategy: validation

Validate before calling

if (userId == null && groupId == null) throw new IllegalArgumentException("userId or groupId required");

Try / catch

try { repositoryService.deleteUserIdentityLinkForCaseDefinition(defId, userId, type); } catch (FlowableIllegalArgumentException e) { log.error("Must supply userId or groupId"); }

Prevention

When it happens

Trigger: Calling deleteUserIdentityLink/deleteGroupIdentityLinkForCaseDefinition with both identity arguments null, e.g. optional parameters forwarded unchanged from an API layer.

Common situations: Admin screens with two optional fields (user/group) submitted empty; scripts parameterized with empty values.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/738f60cf2c02ada8. Report an issue: GitHub.