flowable/flowable-engine · error · FlowableScriptEvaluationException

scriptTrace

Error message

scriptTrace

What it means

ScriptingEngines.evaluate catches exceptions thrown during script evaluation, builds a scriptTrace, and throws FlowableScriptEvaluationException(scriptTrace, e) unless the root cause is already a FlowableException (which is rethrown as-is). The thrown message text is 'scriptTrace' because the exception message is the trace string, not a fixed literal. This is the engine-level wrapper around all script failures.

Solutions

  1. Read the scriptTrace embedded in FlowableScriptEvaluationException to identify the failing script and location.
  2. Inspect getRootCause / cause chain for the underlying ScriptException details.
  3. Fix the script content, bindings, or register the missing scripting engine per the root cause.
  4. Register a ScriptTraceListener/ScriptErrorListener during development to log traces on every failure.

Example fix

// before (swallowing the trace)
catch (Exception e) { log.error("script failed"); }

// after
catch (FlowableScriptEvaluationException e) {
    log.error("Script failed. Trace:\n{}\nRoot cause:", e.getMessage(), ExceptionUtils.getRootCause(e));
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    scriptingEngines.evaluate(script, language, resolver, scopeContainer, inputVariableContainer, storeScriptVariables);
} catch (FlowableScriptEvaluationException e) {
    log.error("Script failed. Trace:\n{}\nRoot cause:", e.getMessage(), org.apache.commons.lang3.exception.ExceptionUtils.getRootCause(e), e);
    throw e;
}

Prevention

When it happens

Trigger: Any failure during script evaluation (ScriptException, engine lookup failure, script syntax/runtime error) that reaches ScriptingEngines.evaluate, including via evaluateScript, renderTaskForm, renderStartForm, or executeScript entry points.

Common situations: Broken script in a BPMN script task; missing scripting engine; script referencing missing variables; debugging via the trace to find which script and line failed.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/scripting/ScriptingEngines.java:86

                enhanceScriptTrace(request, scriptTrace);
                notifyScriptTraceListener(scriptSuccessListener, scriptTrace);
            }
            return evaluationResult;
        } catch (FlowableScriptException e) {
            DefaultScriptTrace scriptTrace = DefaultScriptTrace.errorTrace(Duration.ofNanos(System.nanoTime() - startNanos), request, e);
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Caught exception evaluating script for {}. {}{}{}", request.getScopeContainer(), request.getLanguage(), System.lineSeparator(),
                        request.getScript());
            }
            enhanceScriptTrace(request, scriptTrace);
            if (scriptErrorListener != null) {
                notifyScriptTraceListener(scriptErrorListener, scriptTrace);
            }
            Throwable rootCause = ExceptionUtils.getRootCause(e);
            if (rootCause instanceof FlowableException) {
                throw (FlowableException) rootCause;
            }
            throw new FlowableScriptEvaluationException(scriptTrace, e);
        }
    }

    protected void notifyScriptTraceListener(ScriptTraceListener listener, ScriptTrace scriptTrace) {
        try {
            listener.onScriptTrace(scriptTrace);
        } catch (Exception e) {
            LOGGER.warn("Exception while executing scriptTraceListener: {} with {}", listener, scriptTrace, e);
        }
    }

    protected void enhanceScriptTrace(ScriptEngineRequest request, DefaultScriptTrace scriptTrace) {
        if (defaultTraceEnhancer != null) {
            defaultTraceEnhancer.enhanceScriptTrace(scriptTrace);
        }
        if (request.getTraceEnhancer() != null) {
            request.getTraceEnhancer().enhanceScriptTrace(scriptTrace);
        }

View on GitHub (pinned to d6d39ce1c6)