windmill-labs/windmill · error
QuickJS evaluation error: {}
Error message
QuickJS evaluation error: {} What it means
Generic wrapper: any QuickJS runtime error during expression evaluation that is not a memory-limit abort is converted to 'QuickJS evaluation error: <detail>'. The original QuickJS error text is embedded, e.g. syntax errors, TypeError, undefined variable.
Source
Thrown at backend/windmill-jseval/src/lib.rs:419
}
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)>>,
context_keys: Vec<String>,
memory_limit: usize,
) -> anyhow::Result<Box<RawValue>> {
let runtime = AsyncRuntime::new()?;
runtime.set_memory_limit(memory_limit).await;
let context = AsyncContext::full(&runtime).await?;View on GitHub (pinned to e474e8803c)
Solutions
- Read the embedded QuickJS message to identify the failing expression part
- Test the expression against the actual step data shape (guard optional fields with ?. and ??)
- Fix syntax/runtime errors, then redeploy the flow
Example fix
// before results.user.profile.email // TypeError if profile undefined // after results.user?.profile?.email ?? null
Defensive patterns
Strategy: try-catch
Validate before calling
// guard references before eval
if (!results?.user?.profile) throw new Error('results.user.profile missing'); Try / catch
try {
return await evalExpression(expr, inputs);
} catch (e) {
if (String(e).startsWith('QuickJS evaluation error')) {
console.error('expression failed:', e); // inspect embedded QuickJS message
}
throw e;
} Prevention
- Use optional chaining for possibly-missing fields
- Test expressions against real step data shapes
- Only use JS available in the QuickJS sandbox (no node/browser APIs)
When it happens
Trigger: A transform expression with a JavaScript syntax error, a reference to an undefined variable/property, calling a non-function, or any runtime exception raised inside the QuickJS sandbox.
Common situations: Typos in property names of previous-step results; assuming a field exists on all items of an array; paste-in JS that relies on browser/node APIs unavailable in the sandbox.
Related errors
- The expression evaluation `{expr}` took too long to execute
- The expression evaluation exceeded the memory limit of {} MB
- Job ${jobId} was not successful: ${JSON.stringify(error)}
- Draft flow "${path}" has no value.
- Invalid JSON after replacement: ${message}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/1997f5b24651f71a.
Report an issue: GitHub.