{"record":{"id":"583a12d7d908e8d8","repo":"flowable/flowable-engine","slug":"memory-limit-of-maxmemoryused-bytes-reached","errorCode":null,"errorMessage":"Memory limit of ${maxMemoryUsed} bytes reached","messagePattern":"Memory limit of (.+?) bytes reached","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"modules/flowable-secure-javascript/src/main/java/org/flowable/scripting/secure/impl/SecureScriptContextFactory.java","lineNumber":92,"sourceCode":"        SecureScriptContext context = (SecureScriptContext) cx;\n\n        // Time limit\n        if (maxScriptExecutionTime > 0) {\n            long currentTime = System.currentTimeMillis();\n            if (currentTime - context.getStartTime() > maxScriptExecutionTime) {\n                throw new Error(\"Maximum variableScope time of \" + maxScriptExecutionTime + \" ms exceeded\");\n            }\n        }\n\n        // Memory\n        if (maxMemoryUsed > 0 && threadMxBeanWrapper != null) {\n\n            if (context.getStartMemory() <= 0) {\n                context.setStartMemory(threadMxBeanWrapper.getThreadAllocatedBytes(context.getThreadId()));\n            } else {\n                long currentAllocatedBytes = threadMxBeanWrapper.getThreadAllocatedBytes(context.getThreadId());\n                if (currentAllocatedBytes - context.getStartMemory() >= maxMemoryUsed) {\n                    throw new Error(\"Memory limit of \" + maxMemoryUsed + \" bytes reached\");\n                }\n            }\n\n        }\n    }\n\n    // Override {@link #doTopCall(Callable, Context, Scriptable, Scriptable, Object[])}\n    @Override\n    protected Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {\n        SecureScriptContext mcx = (SecureScriptContext) cx;\n        mcx.setStartTime(System.currentTimeMillis());\n        return super.doTopCall(callable, cx, scope, thisObj, args);\n    }\n\n    public int getOptimizationLevel() {\n        return optimizationLevel;\n    }\n","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-secure-javascript/src/main/java/org/flowable/scripting/secure/impl/SecureScriptContextFactory.java#L74-L110","documentation":"The secure JavaScript sandbox also enforces an allocation memory limit using the ThreadMXBean thread-allocated-bytes counter. In observeInstructionCount, if the bytes allocated by the script thread since it started reach maxMemoryUsed, a java.lang.Error is thrown to kill the script immediately. This prevents memory-exhaustion attacks or accidental OOM from scripts in Flowable script tasks.","triggerScenarios":"A JavaScript script task/listener allocates more memory than the configured maxMemoryUsed (flowable.script memory limit) — building huge arrays/strings, loading big data into the script, or deeply recursive structures; checked on Rhino instruction counts.","commonSituations":"Script concatenating or accumulating very large collections; fetching large process data into JS variables; memory limit configured too low for legitimate work; runaway recursive script.","solutions":["Refactor the script to avoid building large in-memory data structures; process data incrementally.","Increase the maxMemoryUsed configuration if the script legitimately needs more memory.","Move the heavy processing to a Java service task instead of scripting.","Ensure the JVM supports com.sun.management.ThreadMXBean allocation tracking so limits behave predictably."],"exampleFix":"// before: builds one giant string, exceeds memory limit\nvar s = '';\nfor (var i = 0; i < 100000000; i++) { s += i; }\n\n// after: accumulate smaller, or compute without storing everything\nvar total = 0;\nfor (var i = 0; i < 1000000; i++) { total += i; }\nexecution.setVariable('total', total);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  script.execute(execution);\n} catch (Throwable t) {\n  if (t instanceof Error && String(t.getMessage()).startsWith(\"Memory limit of\")) {\n    throw new FlowableException(\"Script exceeded allocation memory limit\", t);\n  }\n  throw t;\n}","preventionTips":["Do not build large arrays/strings in scripts; stream or chunk the work.","Benchmark memory-heavy scripts against maxMemoryUsed before deploying.","Move data-intensive processing into Java service tasks or async jobs.","Raise maxMemoryUsed only after profiling actual script allocation."],"tags":["javascript","scripting","sandbox","memory","flowable"],"backgroundTag":"payload-too-large","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}