flowable/flowable-engine · error · FlowableException

HTTP_TASK_REQUEST_FIELD_INVALID in execution " + execution

Error message

HTTP_TASK_REQUEST_FIELD_INVALID in execution " + execution

What it means

DefaultBpmnHttpActivityDelegate.execute wraps any non-FlowableException raised while building the HTTP request (createRequest) into this FlowableException with code HTTP_TASK_REQUEST_FIELD_INVALID. It signals that a field of the HTTP task's request (URL, method, headers, body expression) could not be resolved or was invalid for the given execution.

Solutions

  1. Inspect the wrapped cause (getCause()) to see the original expression-evaluation failure.
  2. Validate all request fields in the BPMN XML: URL, method, headers, body — ensure referenced variables exist (default them: ${var:defaultValue}).
  3. Test expressions in isolation (e.g. via a small unit test with an ExpressionManager) before deploying the process.
  4. Guard expressions with null-safe checks: ${var != null ? var : ''} or provide defaults via execution listeners.
  5. If your own delegate/field throws, throw FlowableException directly so it isn't double-wrapped.

Example fix

// before
<flowable:field name="requestUrl" expression="${externalUrl}"/> <!-- externalUrl may be null -->

// after
<flowable:field name="requestUrl" expression="${externalUrl != null ? externalUrl : 'https://default.example.com'}"/>
Defensive patterns

Strategy: validation

Validate before calling

// before the http service task runs
Map<String, Object> vars = runtimeService.getVariables(executionId);
if (vars.get("externalUrl") == null || String.valueOf(vars.get("externalUrl")).isBlank()) {
    throw new IllegalArgumentException("externalUrl must be set before HTTP task");
}

Try / catch

try {
    httpActivityDelegate.execute(delegateExecution);
} catch (FlowableException e) {
    if (e.getMessage().startsWith("HTTP_TASK_REQUEST_FIELD_INVALID")) {
        logger.error("invalid http request fields: {}", e.getCause(), e);
    }
}

Prevention

When it happens

Trigger: A service task of type 'http' has request field expressions (httpTask URL, headers, body) that throw when evaluated against the execution — missing variables, bad expression syntax, unresolvable Spring beans, null URL — and the underlying exception is not already a FlowableException.

Common situations: URL expression referencing a variable not present in the execution; typo in variable name; expression returning null for the URL; invalid header expressions; missing Spring bean referenced in an expression; wrong field type in the task's <extensionElements>.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/http/DefaultBpmnHttpActivityDelegate.java:89

    @Override
    protected FlowableHttpClient createHttpClient() {
        HttpClientConfig config = CommandContextUtil.getProcessEngineConfiguration().getHttpClientConfig();
        return config.determineHttpClient();
    }

    @Override
    public CompletableFuture<ExecutionData> execute(DelegateExecution execution, AsyncTaskInvoker taskInvoker) {
        RequestData request;

        HttpServiceTask httpServiceTask = (HttpServiceTask) execution.getCurrentFlowElement();
        try {
            request = createRequest(execution, httpServiceTask.getId());

        } catch (Exception e) {
            if (e instanceof FlowableException) {
                throw (FlowableException) e;
            } else {
                throw new FlowableException(HTTP_TASK_REQUEST_FIELD_INVALID + " in execution " + execution, e);
            }
        }

        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
        HttpRequestHandler httpRequestHandler = createHttpRequestHandler(httpServiceTask.getHttpRequestHandler(), processEngineConfiguration);

        if (httpRequestHandler != null) {
            httpRequestHandler.handleHttpRequest(execution, request.getHttpRequest(), null);
        }

        // Validate request
        validateRequest(request.getHttpRequest());

        boolean parallelInSameTransaction;
        if (httpServiceTask.getParallelInSameTransaction() != null) {
            parallelInSameTransaction = httpServiceTask.getParallelInSameTransaction();
        } else {
            parallelInSameTransaction = processEngineConfiguration.getHttpClientConfig().isDefaultParallelInSameTransaction();

View on GitHub (pinned to d6d39ce1c6)