databendlabs/databend · error
Failed to create now_ms function
Error message
Failed to create now_ms function: {} What it means
A monotonic `metactl.now_ms` clock is registered with mlua's synchronous `create_function`, capturing the setup-time `Instant`. If mlua cannot create the Lua callback wrapper for this closure, the error is wrapped as `Failed to create now_ms function` and environment setup fails.
Solutions
- Check the inner mlua error text; treat memory errors by recreating the Lua instance or raising MemoryLimits.
- Confirm the closure's captured types (`Instant`) are Send/Sync-compatible with the selected mlua features if the build errors instead.
- Re-run in a fresh Lua environment; do not reuse a state that already errored fatally.
- Align/upgrade mlua versions workspace-wide if the inner error indicates an mlua regression.
Defensive patterns
Strategy: try-catch
Try / catch
match setup_lua_environment(&lua) {
Err(e) if e.to_string().contains("Failed to create now_ms function") => {
// treat as environment setup failure; rebuild Lua state
}
other => other?,
} Prevention
- Use a fresh Lua instance per script run so callback slots are never exhausted.
- Keep captured state (e.g. Instant) simple and compatible with the mlua feature set.
- Keep mlua on one pinned version workspace-wide.
- Log the underlying mlua error for diagnosis.
When it happens
Trigger: `lua.create_function(move |_lua, ()| ...)` for `now_ms` failing during `setup_lua_environment` — practically only on Lua allocator/callback-registration failures in the shared runtime.
Common situations: Running metactl Lua scripts in a runtime with exhausted memory or a corrupted Lua state; rarely, an mlua build issue where `create_function` callback slots cannot be allocated.
Related errors
- Failed to create spawn function
- Failed to register spawn function
- Failed to create sleep function
- Failed to register sleep function
- Failed to register now_ms function
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/638938ca94c8f524.
Report an issue: GitHub.
Appendix: source
Thrown at src/meta/control/src/lua_support.rs:470
let sleep_fn = lua
.create_async_function(|_lua, seconds: f64| async move {
let duration = duration_from_seconds(seconds, "sleep")?;
time::sleep(duration).await;
Ok(())
})
.map_err(|e| anyhow::anyhow!("Failed to create sleep function: {}", e))?;
metactl_table
.set("sleep", sleep_fn)
.map_err(|e| anyhow::anyhow!("Failed to register sleep function: {}", e))?;
// Register a monotonic millisecond clock for timing and benchmarks. The
// epoch is this environment's setup time; only differences between calls are
// meaningful. `Instant` guarantees the value never goes backwards.
let start = std::time::Instant::now();
let now_ms_fn = lua
.create_function(move |_lua, ()| Ok(start.elapsed().as_secs_f64() * 1000.0))
.map_err(|e| anyhow::anyhow!("Failed to create now_ms function: {}", e))?;
metactl_table
.set("now_ms", now_ms_fn)
.map_err(|e| anyhow::anyhow!("Failed to register now_ms function: {}", e))?;
// Register the Zipf load generator. The module returns the `ZipfGenerator`
// table, exposed as `metactl.ZipfGenerator` so any script can call
// `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 globalView on GitHub (pinned to 288d84d76e)