zellij-org/zellij · error

No plugin found at '{}'

Error message

No plugin found at '{}'

What it means

move_plugin_to_assets copies each plugin's freshly built wasm from crate::target_dir()/wasm32-wasip1/release/<plugin>.wasm into the assets plugins folder. If that file is not present (checked with is_file()), the copy aborts before starting.

Source

Thrown at xtask/src/build.rs:328

fn move_plugin_to_assets(sh: &Shell, plugin_name: &str) -> anyhow::Result<()> {
    let err_context = || format!("failed to move plugin '{plugin_name}' to assets folder");

    // Get asset path
    let asset_name = crate::asset_dir()
        .join("plugins")
        .join(plugin_name)
        .with_extension("wasm");

    // Get plugin path
    let plugin = crate::target_dir()
        .join("wasm32-wasip1")
        .join("release")
        .join(plugin_name)
        .with_extension("wasm");

    if !plugin.is_file() {
        return Err(anyhow::anyhow!("No plugin found at '{}'", plugin.display()))
            .with_context(err_context);
    }

    // This is a plugin we want to move
    let from = plugin.as_path();
    let to = asset_name.as_path();
    sh.copy_file(from, to).with_context(err_context)
}

View on GitHub (pinned to 98a0837077)

Solutions

  1. Run the full `cargo xtask build` so plugins are compiled for wasm32-wasip1 release before the copy step
  2. Verify the expected file exists: `ls target/wasm32-wasip1/release/*.wasm`, and check whether CARGO_TARGET_DIR redirects the build elsewhere
  3. Install the wasm target: `rustup target add wasm32-wasip1`
  4. If a plugin crate was renamed, update the plugin-name list passed to move_plugin_to_assets to match the new .wasm artifact name

Example fix

# before: copy fails, no wasm present
cargo clean && cargo xtask build --plugins-only   # missing target

# after
rustup target add wasm32-wasip1
cargo xtask build
Defensive patterns

Strategy: validation

Validate before calling

# before any step that copies plugins, verify the wasm artifacts exist
for f in zellij-client/assets/plugins/*.wasm; do :; done  # expected names
ls target/wasm32-wasip1/release/*.wasm >/dev/null 2>&1 || {
  echo 'plugin wasm artifacts missing; run: rustup target add wasm32-wasip1 && cargo xtask build'; exit 1;
}

Type guard

use std::path::Path;

fn plugin_artifact_ready(target_dir: &Path, plugin: &str) -> bool {
    target_dir.join("wasm32-wasip1").join("release")
        .join(plugin).with_extension("wasm")
        .is_file()
}

Try / catch

match build::move_plugin_to_assets(&sh, plugin_name) {
    Err(e) if e.to_string().contains("No plugin found at") => {
        // rebuild plugins for wasm32-wasip1, then retry the copy once
        run!("cargo xtask build --plugins-only")?;
        build::move_plugin_to_assets(&sh, plugin_name)?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Running a build step that includes plugin copying when the wasm32-wasip1 release compile of the plugin was skipped, failed, or landed in a different directory: `cargo clean` between build and copy, CARGO_TARGET_DIR pointing elsewhere, or a renamed plugin crate whose .wasm filename no longer matches.

Common situations: First build on a machine missing the wasm target (`rustup target add wasm32-wasip1`); a plugin build error earlier in the run that was overlooked; stale/renamed plugin lists in xtask config.

Related errors


AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16). Data as JSON: /api/errors/1afd3a448c915317. Report an issue: GitHub.