windmill-labs/windmill · error

The expression evaluation exceeded the memory limit of {} MB

Error message

The expression evaluation exceeded the memory limit of {} MB. {}

What it means

A QuickJS expression evaluation aborted because it hit the configured memory limit. The error is detected from the QuickJS error and mapped to this message, which includes the limit in MB plus remediation advice naming the environment variable that can raise the cap.

Source

Thrown at backend/windmill-jseval/src/lib.rs:413

                .get::<_, Option<String>>("name")
                .ok()
                .flatten()
                .as_deref()
                == Some("InternalError")
                && e.message().as_deref() == Some("out of memory")
        }
        rquickjs::CaughtError::Value(v) => v.is_null() || v.is_undefined(),
        rquickjs::CaughtError::Error(_) => false,
    };
    if is_oom {
        let remediation = match env_override {
            Some(var) => format!(
                "Reduce the amount of data handled in the expression, or raise the \
                 cap via the {var} environment variable."
            ),
            None => "Reduce the amount of data handled in the expression.".to_string(),
        };
        anyhow::anyhow!(
            "The expression evaluation exceeded the memory limit of {} MB. {}",
            memory_limit / (1024 * 1024),
            remediation
        )
    } else {
        anyhow::anyhow!("QuickJS evaluation error: {}", err)
    }
}

#[cfg(feature = "quickjs")]
async fn eval_quickjs_inner(
    expr: &str,
    transform_context: HashMap<String, Arc<Box<RawValue>>>,
    flow_input: Option<mappable_rc::Marc<HashMap<String, Box<RawValue>>>>,
    flow_env: Option<HashMap<String, Box<RawValue>>>,
    authed_client: Option<AuthedClient>,
    by_id: Option<IdContext>,
    extra_ctx: Option<Vec<(String, String)>>,

View on GitHub (pinned to e474e8803c)

Solutions

  1. Reduce the data handled in the expression — pass smaller inputs or filter upstream
  2. Raise the memory cap via the corresponding memory-limit environment variable
  3. Move heavy data processing into a dedicated script step with normal worker memory

Example fix

// before
JSON.stringify(results.hugePayload)  // exceeds memory limit
// after
JSON.stringify({ ids: results.hugePayload.map(x => x.id) })
Defensive patterns

Strategy: validation

Validate before calling

const approxBytes = JSON.stringify(input).length;
if (approxBytes > 5_000_000) throw new Error('input too large for expression eval');

Try / catch

try {
  return await evalExpression(expr, inputs);
} catch (e) {
  if (String(e).includes('exceeded the memory limit')) {
    // reduce payload or raise the memory cap env var and retry once
  }
  throw e;
}

Prevention

When it happens

Trigger: An expression that materializes huge intermediate data — e.g. JSON.stringify on a multi-MB step result, .concat of giant strings, or spreading a very large array — inside a flow step-input transform with a memory cap set.

Common situations: Transforming large API responses directly in an input transform; accidental O(n) copies in a loop; running in environments (especially cloud) with a lowered default memory cap.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/3e665e43605fda1d. Report an issue: GitHub.