DioxusLabs/dioxus · error

failed to expand ifunc table

Error message

failed to expand ifunc table

What it means

During wasm splitting, split and shared functions are routed through an indirect function (funcref) table. expand_ifunc_table_max grows that table by split_points+shared_symbols entries but returns None — triggering this panic — when the funcref table has no declared maximum to grow from.

Source

Thrown at packages/wasm-split/wasm-split-cli/src/lib.rs:411

    /// be filled in from the loaded split module.
    ///
    /// This is because these imports are going to be delayed until the split module is loaded
    /// and loading in the main module these as imports won't be possible since the imports won't
    /// be resolved until the split module is loaded.
    fn create_ifunc_table(&self, out: &mut Module) {
        let ifunc_table = self.load_funcref_table(out);
        let dummy_func = self.make_dummy_func(out);

        out.exports.add("__indirect_function_table", ifunc_table);

        // Expand the ifunc table to accommodate the new ifuncs
        let segment_start = self
            .expand_ifunc_table_max(
                out,
                ifunc_table,
                self.split_points.len() + self.shared_symbols.len(),
            )
            .expect("failed to expand ifunc table");

        // Delete the split import functions and replace them with local functions
        //
        // Start by pushing all the shared imports into the list
        // These don't require an additional stub function
        let mut ifuncs = vec![];

        // Push the split import functions into the list - after we've pushed in the shared imports
        for idx in 0..self.split_points.len() {
            // this is okay since we're in the main module
            let import_func = self.split_points[idx].import_func;
            let import_id = self.split_points[idx].import_id;
            let ty_id = out.funcs.get(import_func).ty();
            let stub_idx = segment_start + ifuncs.len();

            // Replace the import function with a local function that calls the indirect function
            out.funcs.get_mut(import_func).kind =
                self.make_stub_funcs(out, ifunc_table, ty_id, stub_idx as _);

View on GitHub (pinned to 393d190a80)

Solutions

  1. Update dioxus-cli (dx), wasm-bindgen and rustc to versions known to work together, then rebuild
  2. cargo clean and rebuild so wasm-bindgen regenerates the module with a proper table maximum
  3. If it persists, disable wasm code splitting (dx config / web feature) until toolchains align
  4. When invoking wasm-split-cli manually, feed the exact rustc + wasm-bindgen outputs from a single build
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Running the wasm-split step (dx build/serve for web with wasm splitting enabled) on a wasm-bindgen output whose funcref table lacks a maximum field — typically produced by a mismatched rustc/wasm-bindgen/dx toolchain combination, or a module never intended for splitting.

Common situations: Toolchain version skew after upgrading dx or the wasm toolchain without a clean rebuild; custom build pipelines feeding foreign wasm modules into wasm-split-cli.

Related errors


AI-assisted analysis of DioxusLabs/dioxus@393d190a80 (2026-08-16). Data as JSON: /api/errors/242ffc5aaf14296a. Report an issue: GitHub.