flowable/flowable-engine · error · FlowableIllegalArgumentException

injection type is not supported

Error message

injection type is not supported ${injectionType}

What it means

Flowable REST throws FlowableIllegalArgumentException when the injectionType in an inject-activity request is neither 'usertask' nor 'subprocess'. Only those two dynamic injection types are supported by this endpoint.

Solutions

  1. Use injectionType 'usertask' or 'subprocess' only.
  2. For other element types, modify the process definition and redeploy instead of dynamic injection.
  3. Consult DynamicBpmnService in your Flowable version for supported injection capabilities.

Example fix

// before
{"injectionType":"servicetask","id":"svc1"}
// after
{"injectionType":"usertask","id":"userTask2","name":"Manual step"}
Defensive patterns

Strategy: validation

Validate before calling

if (!['usertask','subprocess'].includes(injectionType.toLowerCase())) throw new Error('unsupported injectionType: ' + injectionType);

Type guard

const isInjectableType = (t) => ['usertask','subprocess'].includes(String(t).toLowerCase());

Prevention

When it happens

Trigger: POST /runtime/process-instances/{id}/inject-activity with {"injectionType":"servicetask"} or any value other than 'usertask'/'subprocess' (comparison is case-insensitive).

Common situations: Developer assumes all BPMN element types can be injected dynamically; copy-paste of 'injectionType' from other tooling; version differences in supported dynamic injection features.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ProcessInstanceResource.java:316

                dynamicBpmnService.injectUserTaskInProcessInstance(processInstanceId, taskBuilder);
            }
        
        } else if ("subprocess".equalsIgnoreCase(injectActivityRequest.getInjectionType())) {
            if (StringUtils.isEmpty(injectActivityRequest.getProcessDefinitionId())) {
                throw new FlowableIllegalArgumentException("processDefinitionId is required");
            }
            DynamicEmbeddedSubProcessBuilder subProcessBuilder = new DynamicEmbeddedSubProcessBuilder();
            subProcessBuilder.id(injectActivityRequest.getId())
                .processDefinitionId(injectActivityRequest.getProcessDefinitionId());
            
            if (injectActivityRequest.getTaskId() != null) {
                dynamicBpmnService.injectParallelEmbeddedSubProcess(injectActivityRequest.getTaskId(), subProcessBuilder);
            } else {
                dynamicBpmnService.injectEmbeddedSubProcessInProcessInstance(processInstanceId, subProcessBuilder);
            }
        
        } else {
            throw new FlowableIllegalArgumentException("injection type is not supported " + injectActivityRequest.getInjectionType());
        }
    }

    protected ProcessInstanceResponse activateProcessInstance(ProcessInstance processInstance) {
        if (!processInstance.isSuspended()) {
            throw new FlowableConflictException("Process instance with id '" + processInstance.getId() + "' is already active.");
        }
        runtimeService.activateProcessInstanceById(processInstance.getId());

        ProcessInstanceResponse response = restResponseFactory.createProcessInstanceResponse(processInstance);

        // No need to re-fetch the instance, just alter the suspended state of the result-object
        response.setSuspended(false);
        return response;
    }

    protected ProcessInstanceResponse suspendProcessInstance(ProcessInstance processInstance) {
        if (processInstance.isSuspended()) {

View on GitHub (pinned to d6d39ce1c6)