clockworklabs/SpacetimeDB · critical
{CALL_VIEW_ANON_DUNDER} export is not a function
Error message
{CALL_VIEW_ANON_DUNDER} export is not a function What it means
get_call_view_anon resolves the `__call_view_anon__` export, the entry point for anonymous views. `Export::into_func()` returns None when that name is exported as a memory, global, or table, and the host panics because a non-function entry is unrecoverable. The export is optional (absent name yields None), so the panic only fires when something occupies the name with the wrong kind.
Source
Thrown at crates/core/src/host/wasmtime/wasmtime_module.rs:483
let export = instance.get_export(store.as_context_mut(), CALL_VIEW_DUNDER)?;
Some(
export
.into_func()
.unwrap_or_else(|| panic!("{CALL_VIEW_DUNDER} export is not a function"))
.typed(store)
.unwrap_or_else(|err| panic!("{CALL_VIEW_DUNDER} export is a function with incorrect type: {err}")),
)
}
/// Look up the `instance`'s export named by [`CALL_VIEW_ANON_DUNDER`].
///
/// Similar to [`get_call_procedure`], but for anonymous views.
fn get_call_view_anon(store: &mut Store<WasmInstanceEnv>, instance: &Instance) -> Option<CallViewAnonType> {
let export = instance.get_export(store.as_context_mut(), CALL_VIEW_ANON_DUNDER)?;
Some(
export
.into_func()
.unwrap_or_else(|| panic!("{CALL_VIEW_ANON_DUNDER} export is not a function"))
.typed(store)
.unwrap_or_else(|err| panic!("{CALL_VIEW_ANON_DUNDER} export is a function with incorrect type: {err}")),
)
}
/// Look up the `instance`'s export named by [`CALL_HTTP_HANDLER_DUNDER`].
///
/// Similar to [`get_call_procedure`], but for HTTP handlers.
fn get_call_http_handler(store: &mut Store<WasmInstanceEnv>, instance: &Instance) -> Option<CallHttpHandlerType> {
let export = instance.get_export(store.as_context_mut(), CALL_HTTP_HANDLER_DUNDER)?;
Some(
export
.into_func()
.unwrap_or_else(|| panic!("{CALL_HTTP_HANDLER_DUNDER} export is not a function"))
.typed(store)
.unwrap_or_else(|err| panic!("{CALL_HTTP_HANDLER_DUNDER} export is a function with incorrect type: {err}")),
)
}View on GitHub (pinned to 6dee26c6ef)
Solutions
- Run `wasm-objdump -x module.wasm | grep -A2 __call_view_anon__` to identify the export kind.
- Rename or remove the conflicting export in module source and rebuild.
- Regenerate the module with the official SDK so only functions carry the dunder names.
Defensive patterns
Strategy: type-guard
Validate before calling
use wasmtime::{Engine, Module, ExternType};
fn anon_view_export_is_func(engine: &Engine, wasm: &[u8]) -> Result<(), String> {
let module = Module::new(engine, wasm).map_err(|e| e.to_string())?;
if let Some(exp) = module.get_export("__call_view_anon__") {
if !matches!(exp.ty(), ExternType::Func(_)) {
return Err(format!("__call_view_anon__ exported as {:?}, not a function", exp.ty()));
}
}
Ok(())
} Type guard
fn is_func_export(ty: &ExternType) -> bool { matches!(ty, ExternType::Func(_)) } Prevention
- Reserve dunder export names in code review checklists for module code.
- Automate an export-kind scan over built wasm in CI.
- Regenerate modules with the official SDK rather than editing exports by hand.
When it happens
Trigger: Instantiating a module that exports `__call_view_anon__` as a non-function item (global/memory/table); reached in get_call_view_anon during publish or module host startup.
Common situations: Accidental export name collision with the reserved dunder name in module code or WAT; tooling that exports globals with mangled names colliding after a rename; forks that renamed anonymous view entries.
Related errors
- {CALL_VIEW_DUNDER} export is not a function
- {CALL_VIEW_ANON_DUNDER} export is a function with incorrect
- {CALL_HTTP_HANDLER_DUNDER} export is not a function
- {CALL_PROCEDURE_DUNDER} export is not a function
- {CALL_PROCEDURE_DUNDER} export is a function with incorrect
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/f16515766046c502.
Report an issue: GitHub.