databendlabs/databend · error

Failed to load lua_util functions

Error message

Failed to load lua_util functions: {}

What it means

Finally, `setup_lua_environment` executes the embedded `LUA_UTIL` Lua chunk, which defines utility functions such as `metactl.to_string`. This error wraps any failure of `lua.load(LUA_UTIL).exec()` — a compile (syntax) error in the embedded source or a runtime error while it executes.

Solutions

  1. Read the inner error text: syntax errors point at recent edits to the LUA_UTIL constant; runtime nil-index errors point at setup ordering.
  2. Keep this `exec()` after the `metactl` global is registered, and have LUA_UTIL only assign into the existing table.
  3. Verify the mlua Lua-version feature supports the syntax used in LUA_UTIL (e.g. integer division, goto).
  4. Evaluate the chunk standalone with the same Lua version to locate the failing statement.

Example fix

// before: util chunk assumes metactl exists
to_string = function(v) ... end
// after: assign into the existing namespace
metactl.to_string = function(v) ... end
Defensive patterns

Strategy: validation

Validate before calling

// CI test: LUA_UTIL must exec cleanly and define metactl.to_string
setup_lua_environment(&lua)?;
let f: mlua::Function = lua.globals().get::<_, mlua::Table>("metactl")?.get("to_string")?;
let _ = f.call::<_, ()>("x")?;

Try / catch

match setup_lua_environment(&lua) {
    Err(e) if e.to_string().contains("Failed to load lua_util functions") => {
        // embedded LUA_UTIL broken: surface inner Lua syntax/runtime error
    }
    other => other?,
}

Prevention

When it happens

Trigger: Running `lua.load(LUA_UTIL).exec()` during `setup_lua_environment` fails: the LUA_UTIL constant has a Lua syntax error, or its top-level statements raise a runtime error (e.g. indexing a missing `metactl` global, which would indicate the namespace registration above was skipped).

Common situations: After editing the LUA_UTIL constant and introducing a typo, running under an mlua Lua version that rejects syntax used in the chunk, or reordering setup so LUA_UTIL runs before the `metactl` global exists.

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/e420941f5d11d54f. Report an issue: GitHub.

Appendix: source

Thrown at src/meta/control/src/lua_support.rs:496

    // `metactl.ZipfGenerator:new(num_keys, alpha)` directly.
    let zipf_generator = lua
        .load(ZIPF_LOAD_GENERATOR)
        .eval::<Table>()
        .map_err(|e| anyhow::anyhow!("Failed to load zipf_load_generator: {}", e))?;

    metactl_table
        .set("ZipfGenerator", zipf_generator)
        .map_err(|e| anyhow::anyhow!("Failed to register ZipfGenerator: {}", e))?;

    // Set the metactl table as a global
    lua.globals()
        .set("metactl", metactl_table)
        .map_err(|e| anyhow::anyhow!("Failed to register metactl namespace: {}", e))?;

    // Load lua_util functions (which registers to_string in metactl namespace)
    lua.load(LUA_UTIL)
        .exec()
        .map_err(|e| anyhow::anyhow!("Failed to load lua_util functions: {}", e))?;

    Ok(())
}

pub fn new_grpc_client(
    addresses: Vec<String>,
) -> Result<Arc<ClientHandle<DatabendRuntime>>, CreationError> {
    eprintln!(
        "Using gRPC API address: {}",
        serde_json::to_string(&addresses).unwrap()
    );
    MetaGrpcClient::try_create(
        addresses,
        "root",
        "xxx",
        Some(Duration::from_secs(2)),
        Some(Duration::from_secs(1)),
        None,

View on GitHub (pinned to 288d84d76e)