unionlabs/union · error
not implemented
Error message
not implemented
What it means
extract_wasm statically instantiates the target module under wasmer, stubbing every imported function with a host closure whose body is unimplemented!(). The assumption is that commit_hash (emitted by the embed-commit crate as a pure function that only writes its 32-byte Rev return value to linear memory) never calls imports. If a verified module's commit_hash does call an import, the stub panics, surfacing as a trap/runtime error from commit_hash_fn.call.
Source
Thrown at lib/embed-commit/verifier/src/lib.rs:59
/// Retrieve the git rev from the provided wasm binary bytes.
///
/// # Errors
///
/// This function will error if the wasm binary bytes provided cannot be parsed, or if the returned git rev cannot be parsed. If there is no `commit_hash` export then `Ok(None)` will be returned.
pub fn extract_wasm(bz: &[u8]) -> Result<Option<Rev>> {
let engine = Engine::default();
let module = Module::from_binary(&engine, bz)?;
let mut linker = Linker::new(&engine);
let mut store: Store<()> = Store::new(&engine, ());
// stub all imports as they're unused when evaluating commit_hash
for import in module.imports() {
linker.func_new(
import.module(),
import.name(),
import.ty().unwrap_func().clone(),
|_, _, _| unimplemented!(),
)?;
}
let instance = linker.instantiate(&mut store, &module)?;
let Ok(commit_hash_fn) = instance.get_typed_func::<i32, ()>(&mut store, "commit_hash") else {
return Ok(None);
};
commit_hash_fn.call(&mut store, 0)?;
let memory = instance
.get_memory(&mut store, "memory")
.context("reading memory export")?;
bytemuck::checked::try_from_bytes::<Rev>(&memory.data(&store)[0..std::mem::size_of::<Rev>()])
.map_err(|e| anyhow!(e.to_string()))
.context("parsing rev")View on GitHub (pinned to 031785bb6d)
Solutions
- Only run the verifier over artifacts built by the union embed-commit toolchain
- Change the stub to return an Err (or wrap the call in catch_unwind) so a foreign module yields a typed 'not an embed-commit binary' result instead of a panic
- Keep producer and verifier embed-commit crate versions in lockstep
- Where possible, pre-check for a producer marker (e.g., a custom section) before executing the module
Example fix
// before
for import in module.imports() {
linker.func_new(import.module(), import.name(), import.ty().unwrap_func().clone(), |_, _, _| unimplemented!())?;
}
// after — surface a typed error instead of panicking when an import is reached
for import in module.imports() {
linker.func_new(
import.module(), import.name(), import.ty().unwrap_func().clone(),
|_, _, _| Err(wasmer::RuntimeError::new("import called while evaluating commit_hash; not an embed-commit module")),
)?;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Cheap structural pre-check: only modules with a commit_hash export are candidates
let hasCommitHash = false
for (const exp of module.exports()) {
if (exp.name() === "commit_hash") hasCommitHash = true
}
if (!hasCommitHash) return Ok(None) Try / catch
// Keep the host alive if a foreign module calls a stubbed import
let outcome = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
commit_hash_fn.call(&mut store, 0)
}));
match outcome {
Ok(Ok(())) => { /* read memory[0..32] as Rev */ }
Ok(Err(_trap)) | Err(_panic) => {
// commit_hash called an import or trapped: not an embed-commit module
return Ok(None);
}
} Prevention
- Only verify artifacts produced by the union embed-commit toolchain
- Run verification in a subprocess or catch_unwind boundary so panics cannot kill the host
- Keep embed-commit versions identical between producer and verifier
- Treat 'import called during commit_hash' as a classification (foreign module), not an error to retry
When it happens
Trigger: Verifying a wasm that exports commit_hash but whose body calls an imported function — i.e., a binary not produced by the union embed-commit toolchain, or a toolchain revision where commit_hash got linked against imports.
Common situations: Feeding arbitrary third-party wasm into the verifier; producer and verifier built from different embed-commit versions; post-processing tools that rewrite the module and introduce import calls.
Related errors
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/722e73871b2c6111.
Report an issue: GitHub.