flowable/flowable-engine · error · Error

Maximum variableScope time of ${maxScriptExecutionTime} ms e

Error message

Maximum variableScope time of ${maxScriptExecutionTime} ms exceeded

What it means

The Flowable secure JavaScript sandbox (flowable-secure-javascript) enforces a wall-clock time limit on script execution. The Rhino instruction-observation hook (observeInstructionCount) periodically checks elapsed time since the script started and throws a plain java.lang.Error (not an Exception) once maxScriptExecutionTime is exceeded, immediately terminating the script. This is a deliberate sandbox kill to stop runaway/infinite-loop scripts in script tasks and listeners.

Source

Thrown at modules/flowable-secure-javascript/src/main/java/org/flowable/scripting/secure/impl/SecureScriptContextFactory.java:80

        // Max stack depth
        if (maxStackDepth > 0) {
            context.setOptimizationLevel(-1); // stack depth can only be set when no optimizations are applied
            context.setMaximumInterpreterStackDepth(maxStackDepth);
        }

        return context;
    }

    @Override
    protected void observeInstructionCount(Context cx, int instructionCount) {
        SecureScriptContext context = (SecureScriptContext) cx;

        // Time limit
        if (maxScriptExecutionTime > 0) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - context.getStartTime() > maxScriptExecutionTime) {
                throw new Error("Maximum variableScope time of " + maxScriptExecutionTime + " ms exceeded");
            }
        }

        // Memory
        if (maxMemoryUsed > 0 && threadMxBeanWrapper != null) {

            if (context.getStartMemory() <= 0) {
                context.setStartMemory(threadMxBeanWrapper.getThreadAllocatedBytes(context.getThreadId()));
            } else {
                long currentAllocatedBytes = threadMxBeanWrapper.getThreadAllocatedBytes(context.getThreadId());
                if (currentAllocatedBytes - context.getStartMemory() >= maxMemoryUsed) {
                    throw new Error("Memory limit of " + maxMemoryUsed + " bytes reached");
                }
            }

        }
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Fix the script: remove infinite/unbounded loops and heavy computation from the script task.
  2. Increase the max script execution time setting if the workload is legitimately long-running.
  3. Move long work out of the script into a service task or async job.
  4. Catch/handle the Error at the process level so the process instance fails gracefully with a clear message.

Example fix

// before: sandbox killed for running too long
var i = 0; while (true) { i++; }

// after: bounded loop
var i = 0;
while (i < 1000) { i++; }
execution.setVariable('count', i);
Defensive patterns

Strategy: try-catch

Try / catch

try {
  script.execute(execution);
} catch (Throwable t) {
  if (t instanceof Error && String(t.getMessage()).startsWith("Maximum variableScope time of")) {
    throw new FlowableException("Script exceeded configured time limit; failing task gracefully", t);
  }
  throw t;
}

Prevention

When it happens

Trigger: A JavaScript script task / execution or task listener runs longer than the configured maxScriptExecutionTime (flowable.script... limit) — heavy loops, waits, or infinite loops inside the script; triggers during Rhino bytecode instruction callbacks.

Common situations: while(true) or unbounded loop in a script task; script doing expensive computation on large collections; too-low maxScriptExecutionTime configured for a legitimately heavy script; blocking call inside JS script.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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