{"record":{"id":"2908b3a3a13d0668","repo":"wasmerio/wasmer","slug":"internal-error-function-table-index-index-alrea","errorCode":null,"errorMessage":"Internal error: function table index {index} already occupied","messagePattern":"Internal error: function table index (.+?) already occupied","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/wasix/src/state/linker/instance_group/table.rs","lineNumber":88,"sourceCode":"            ?func,\n            \"Placing function in table at pre-defined index\"\n        );\n\n        let table = &self.indirect_function_table;\n        let size = table.size(store);\n\n        if size <= index {\n            let delta = index - size + 1;\n            trace!(\n                current_size = ?size,\n                ?delta,\n                \"Growing indirect function table\"\n            );\n            table.grow(store, delta, Value::FuncRef(None))?;\n        } else {\n            let existing = table.get(store, index).unwrap();\n            if let Value::FuncRef(Some(_)) = existing {\n                panic!(\"Internal error: function table index {index} already occupied\");\n            }\n        }\n\n        let ty = func.ty(store).to_string();\n        trace!(?index, ?ty, \"Placing function in table at index\");\n        table.set(store, index, Value::FuncRef(Some(func)))\n    }\n\n    pub(super) fn allocate_function_table_for_existing_module(\n        &mut self,\n        linker_state: &LinkerState,\n        store: &mut impl AsStoreMut,\n        module_handle: ModuleHandle,\n    ) -> Result<(), LinkError> {\n        if self.side_instances.contains_key(&module_handle) {\n            panic!(\n                \"Internal error: Module with handle {module_handle:?} \\\n                was already instantiated in this group\"","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/wasix/src/state/linker/instance_group/table.rs#L70-L106","documentation":"place_in_function_table_at panics when trying to write a resolved function reference into an element of the indirect function table that already holds a live FuncRef. The linker assumes each allocated table slot is empty before placement; a non-null entry means the allocation/placement bookkeeping is out of sync. It is an internal invariant check for the dynamic-linking (dlopen-style) function table.","triggerScenarios":"apply_dl_operation / populate_imports_from_linker / finalize_pending_resolutions_from_linker placing two resolved functions at the same table index; re-running apply_resolved_function for an index that was already populated; a table_base misalignment causing index overlap.","commonSituations":"Loading the same shared module twice into one instance group; table_size/table_alignment metadata (dylink info) of the compiled shared module not matching what the linker assumed; repeated finalize calls on the same linker state.","solutions":["Ensure each shared module is instantiated only once per InstanceGroup (deduplicate dlopen of the same path)","Recompile the shared modules so their dylink metadata (table_size, table_base, alignment) is consistent with the current compiler version","Avoid calling finalize_pending_resolutions_from_linker / populate_imports_from_linker more than once for the same group","Clear or rebuild the instance group if it was reused across link runs"],"exampleFix":"// before: reusing the same instance group for a second dlopen of the same module\ngroup.apply_dl_operation(DlOperation::Load { module: same_handle, ... });\n// after: check before loading\nif !group.contains_module(&same_handle) {\n    group.apply_dl_operation(DlOperation::Load { module: same_handle, ... });\n}","handlingStrategy":"validation","validationCode":"fn slot_is_free(store: &impl AsStoreRef, table: &Table, index: u64) -> bool {\n    !matches!(table.get(store, index), Some(Value::FuncRef(Some(_))))\n}\n// check before placement: if !slot_is_free(store, &table, index) { skip or reallocate }","typeGuard":"fn is_free_slot(v: Option<&Value>) -> bool {\n    !matches!(v, Some(Value::FuncRef(Some(_))))\n}","tryCatchPattern":null,"preventionTips":["Instantiate each shared module only once per group","Run finalize/populate passes exactly once per link run","Keep dylink metadata (table_size/base) from a single compiler version","Rebuild the instance group rather than reusing a mutated table"],"tags":["linker","function-table","internal-invariant","panic"],"backgroundTag":"function-table-slot-conflict","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}