wasmerio/wasmer · critical

Internal error: bad in-progress symbol resolution

Error message

Internal error: bad in-progress symbol resolution

What it means

During import population, a memory-address computation encountered a PartiallyResolvedExport::Function where only memory/global addresses are valid. A function export cannot provide a memory offset address, so reaching it means the resolver assigned the wrong export kind to the symbol — an internal invariant violation, hence a bare panic.

Source

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

                        PartiallyResolvedExport::Tls { offset, final_addr } => {
                            trace!(?module_handle, ?import, offset, final_addr, "TLS address");

                            let global =
                                define_integer_global_import(store, &import, final_addr).unwrap();

                            imports.define(import.module(), import.name(), global);
                            linker_state.symbol_resolution_records.insert(
                                SymbolResolutionKey::Needed(key.clone()),
                                SymbolResolutionResult::Tls {
                                    resolved_from: *module_handle,
                                    offset,
                                },
                            );
                        }

                        PartiallyResolvedExport::Function(_) => {
                            panic!("Internal error: bad in-progress symbol resolution")
                        }
                    }
                }

                InProgressSymbolResolution::UnresolvedMemGlobal => {
                    let global = define_integer_global_import(store, &import, 0).unwrap();
                    imports.define(import.module(), import.name(), global.clone());

                    link_state
                        .unresolved_globals
                        .push(UnresolvedGlobal::Mem(key, global));
                }

                InProgressSymbolResolution::FuncGlobal(module_handle) => {
                    let func = self
                        .instance(*module_handle)
                        .exports
                        .get_function(import.name())

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Check which symbol maps to PartiallyResolvedExport::Function and verify the exporting module actually exports a memory/global (not a function) under that name.
  2. Fix symbol collisions/renames so the expected memory or global is exported under the imported name.
  3. Validate export kinds in the link-state resolver before replaying them as memory addresses.
  4. Reproduce upstream if it occurs with standard pic-linking flows and report to wasmtime with the module pair.

Example fix

// before: wrong export kind recorded during resolution
let addr = match export { PartiallyResolvedExport::Global(addr) => addr, ... PartiallyResolvedExport::Function(_) => panic!(...) };
// after: reject early with a typed link error
if matches!(export, PartiallyResolvedExport::Function(_)) {
    return Err(LinkError::ExpectedMemoryOrGlobalExport(import.name().to_string()));
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Before populating, ensure memory/global imports did not resolve to function exports
fn export_kind_ok(res: &InProgressSymbolResolution, expected: ImportKind) -> bool {
    match (res, expected) {
        (InProgressSymbolResolution::Resolved(PartiallyResolvedExport::Function(_)), ImportKind::Func)
        | (InProgressSymbolResolution::Resolved(PartiallyResolvedExport::Global(_)), ImportKind::Global) => true,
        _ => false,
    }
}

Type guard

fn is_memory_or_global(e: &PartiallyResolvedExport) -> bool {
    !matches!(e, PartiallyResolvedExport::Function(_))
}

Prevention

When it happens

Trigger: populate_imports_from_link_state handling an InProgressSymbolResolution whose PartiallyResolvedExport is Function(_) while computing a memory offset — i.e. the link state recorded a function export for a symbol the importer expects to be a memory or global address.

Common situations: Side modules importing a memory-relative symbol (e.g. for static data) that was resolved against a function export in the exporting module; symbol-name collisions resolving to the wrong export type; hand-built LinkStates with mismatched export kinds.

Related errors


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