databendlabs/databend · error
Lua execution error
Error message
Lua execution error: {} What it means
run_lua_script executes a Lua script on an mlua async runtime. If `lua.load(script).exec_async()` returns Err — a syntax error, a runtime error raised by the script (via `error()`), or a callback error — the function wraps it in anyhow with "Lua execution error: {}". This is a pass-through wrapper: the real cause is in the inner Lua error message.
Solutions
- Read the inner Lua error after 'Lua execution error:' to find the failing line/function in the script
- Validate the script syntax with a standalone lua interpreter (luac -p) before running it against meta
- Fix the nil reference or error() call inside the Lua script
- If a Rust callback is the cause, fix that function's error condition
Example fix
// before: run script directly and get opaque failure
run_lua_script(&script).await?;
// after: smoke-test compile first (in a test)
let lua = mlua::Lua::new();
lua.load(&script).exec_async().await
.expect("script must compile and run"); Defensive patterns
Strategy: try-catch
Validate before calling
if let Err(e) = luac_check(&script) { bail!("script will not compile: {e}"); } Type guard
fn is_compilable_lua(script: &str) -> bool { luac_syntax_check(script).is_ok() } Try / catch
match run_lua_script(&script).await {
Ok(()) => {},
Err(e) if e.to_string().contains("Lua execution error") => log::error!("lua script failed: {e:#}"),
Err(e) => return Err(e),
} Prevention
- Lint Lua scripts with luac -p before deploying
- Keep a test harness that executes every maintenance script against a test meta
- Avoid top-level error(); return errors as values
When it happens
Trigger: Calling run_lua_script(script) where the script fails to compile (syntax error), calls error()/panic, references a nil global, or a Rust-registered function it calls returns an error.
Common situations: Meta-service Lua maintenance/upgrade scripts edited by hand with typos; scripts assuming tables or APIs that don't exist in the embedded runtime; scripts that raise errors on unexpected meta data state.
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
- Unsupported format for
- Unsupported source type. Expected path, pandas.DataFrame…
- Access denied: is outside allowed directories
- rename_database: src (db) should exist
- internal error: expect TxnGetResponseGet of get database…
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/95f3418cea02221a.
Report an issue: GitHub.
Appendix: source
Thrown at src/meta/control/src/lua_support.rs:533
DEFAULT_GRPC_MESSAGE_SIZE,
)
}
pub fn new_admin_client(addr: &str) -> MetaAdminClient {
MetaAdminClient::new(addr)
}
pub async fn run_lua_script(script: &str) -> anyhow::Result<()> {
let lua = Lua::new();
setup_lua_environment(&lua)?;
#[allow(clippy::disallowed_types)]
let local = tokio::task::LocalSet::new();
let res = local.run_until(lua.load(script).exec_async()).await;
if let Err(e) = res {
return Err(anyhow::anyhow!("Lua execution error: {}", e));
}
Ok(())
}
pub async fn run_lua_script_with_result(
script: &str,
) -> anyhow::Result<Result<Option<String>, String>> {
let lua = Lua::new();
setup_lua_environment(&lua)?;
#[allow(clippy::disallowed_types)]
let local = tokio::task::LocalSet::new();
let res = local
.run_until(lua.load(script).eval_async::<mlua::MultiValue>())
.await;
match res {View on GitHub (pinned to 288d84d76e)