flowable/flowable-engine · error · FlowableIllegalArgumentException

" + delegateInstance.getClass().getName() + " doesn't implem

Error message

" + delegateInstance.getClass().getName() + " doesn't implement " + HttpRequestHandler.class

What it means

ClassDelegateHttpHandler.getHttpRequestHandlerInstance throws this FlowableIllegalArgumentException when the class configured as an HTTP request handler (via className) is instantiated but does not implement the HttpRequestHandler interface. The engine verifies the contract after instantiation and refuses to use an incompatible class.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/http/handler/ClassDelegateHttpHandler.java:67

    @Override
    public void handleHttpRequest(VariableContainer execution, HttpRequest httpRequest, FlowableHttpClient client) {
        HttpRequestHandler httpRequestHandler = getHttpRequestHandlerInstance();
        CommandContextUtil.getProcessEngineConfiguration().getDelegateInterceptor().handleInvocation(new HttpRequestHandlerInvocation(httpRequestHandler, execution, httpRequest, client));
    }

    @Override
    public void handleHttpResponse(VariableContainer execution, HttpResponse httpResponse) {
        HttpResponseHandler httpResponseHandler = getHttpResponseHandlerInstance();
        CommandContextUtil.getProcessEngineConfiguration().getDelegateInterceptor().handleInvocation(new HttpResponseHandlerInvocation(httpResponseHandler, execution, httpResponse));
    }

    protected HttpRequestHandler getHttpRequestHandlerInstance() {
        Object delegateInstance = instantiateDelegate(className, fieldDeclarations);
        if (delegateInstance instanceof HttpRequestHandler) {
            return (HttpRequestHandler) delegateInstance;
        } else {
            throw new FlowableIllegalArgumentException(delegateInstance.getClass().getName() + " doesn't implement " + HttpRequestHandler.class);
        }
    }

    protected HttpResponseHandler getHttpResponseHandlerInstance() {
        Object delegateInstance = instantiateDelegate(className, fieldDeclarations);
        if (delegateInstance instanceof HttpResponseHandler) {
            return (HttpResponseHandler) delegateInstance;
        } else {
            throw new FlowableIllegalArgumentException(delegateInstance.getClass().getName() + " doesn't implement " + HttpResponseHandler.class);
        }
    }

}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Make the configured class implement org.flowable.http.HttpRequestHandler (add httpRequest(...)) or change the config to a class that does.
  2. Double-check configuration: request handler fields must reference a request handler; response handler fields a response handler — swap if inverted.
  3. Verify the package: there are historically similar interfaces (HttpRequestHandler in different modules); import the one the engine expects.
  4. Add a startup/unit test that instantiates the handler and asserts instanceof HttpRequestHandler to fail fast.

Example fix

// before
public class MyHandler { public void handle(...) {...} }

// after
public class MyHandler implements HttpRequestHandler {
    @Override
    public void httpRequest(ExecuteHttpRequest request) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = Class.forName(configuredRequestHandlerClass);
if (!HttpRequestHandler.class.isAssignableFrom(c)) {
    throw new IllegalStateException(configuredRequestHandlerClass + " must implement HttpRequestHandler");
}

Type guard

static boolean isRequestHandler(String className) throws ClassNotFoundException {
    return HttpRequestHandler.class.isAssignableFrom(Class.forName(className));
}

Try / catch

try {
    handler.getHttpRequestHandlerInstance();
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("doesn't implement")) {
        // swap in a compliant default handler
    }
}

Prevention

When it happens

Trigger: httpActivityHandler / HTTP task configuration specifies a delegate class whose name implements HttpResponseHandler (or nothing relevant) but not HttpRequestHandler; ClassDelegateHttpHandler is constructed with that className and lazily instantiates it when a request handler is needed.

Common situations: Copy-paste of a response handler class into the request-handler config slot; refactoring renamed/moved interfaces (e.g. between flowable-http and engine modules); missing 'implements HttpRequestHandler' after auto-generating a class; mixing up handlerClass and handler configuration properties in engine config.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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