wasmerio/wasmer · critical

Internal error: failed to resolve function {}: {e:?}

Error message

Internal error: failed to resolve function {}: {e:?}

What it means

populate_imports_from_linker resolves a function import by fetching it from the exporting instance's exports. If get_function fails at this late stage — after the symbol was already recorded as resolved — the replay diverged from the recorded resolution, indicating an internal inconsistency, so it panics with the failing import name.

Source

Thrown at lib/wasix/src/state/linker/instance_group/imports.rs:331

                    let func = self.generate_stub_function(
                        store,
                        ty,
                        env,
                        module_handle,
                        import.name().to_owned(),
                    );
                    imports.define(import.module(), import.name(), func.clone());
                }
                SymbolResolutionResult::FunctionPointer {
                    resolved_from,
                    function_table_index,
                } => {
                    let func = self.try_instance(*resolved_from).map(|instance| {
                        instance
                            .exports
                            .get_function(import.name())
                            .unwrap_or_else(|e| {
                                panic!(
                                    "Internal error: failed to resolve function {}: {e:?}",
                                    import.name()
                                )
                            })
                    });
                    match func {
                        Some(func) => {
                            trace!(
                                ?module_handle,
                                ?import,
                                function_table_index,
                                "Placing function pointer into table"
                            );
                            self.place_in_function_table_at(
                                store,
                                func.clone(),
                                *function_table_index,
                            )

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Verify the resolution record's resolved_from instance actually exports import.name() (log instance exports at record time).
  2. Ensure instances are created and registered in the same order/indices between resolution recording and population.
  3. Do not mutate linker state or instance exports between the two passes.
  4. Reproduce with a minimal module pair on stock wasmtime and report upstream if it still panics.

Example fix

// before
instance.exports.get_function(import.name()).unwrap_or_else(|e| panic!(...))
// after: re-validate against resolution record, fail as LinkError
let func = instance.exports.get_function(import.name())
    .map_err(|e| LinkError::FunctionResolutionFailed(import.name().to_string(), e))?;
Defensive patterns

Strategy: validation

Validate before calling

// Before populating, confirm each recorded function resolution is fetchable
if let Some(rec) = linker_state.symbol_resolution_records.get(&key) {
    if let Some(idx) = rec.resolved_from() {
        if let Some(inst) = group.try_instance(idx) {
            assert!(inst.exports.get_function(import.name()).is_ok(),
                "recorded function {} missing from instance {}", import.name(), idx);
        }
    }
}

Try / catch

// Defensive isolation for custom linker flows:
let result = std::panic::catch_unwind(|| group.populate_imports_from_linker(&mut store, &linker_state));
match result {
    Ok(r) => r,
    Err(_) => Err(LinkError::FunctionResolutionFailed(import_name)),
}

Prevention

When it happens

Trigger: create_instance_group/prepare_side_module_from_linker where a recorded function resolution points at an instance (resolved_from) whose exports do not contain import.name() — e.g. wrong instance index in the resolution record, exports changed/overridden between record and population, or a mismatched symbol record type.

Common situations: dlopen-style linking where a side module's import resolved to an instance that was later replaced or not instantiated; custom linker forks editing resolution records; symbol names shadowed by env/config imports registered after resolution.

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/7e3b9f711e3a5b89. Report an issue: GitHub.