ruvnet/RuView · error
plugin `{id}` setup returned failure code {result}
Error message
plugin `{id}` setup returned failure code {result} What it means
Anyhow bail during WASM plugin loading: the module loaded and its exported setup was invoked (call_setup with a bootstrap ConfigEntryJson), but the guest returned a non-zero exit code. The host reacts by calling the plugin's teardown, running teardown_wasm over already-loaded plugins, and aborting server startup with the plugin id and the exact failure code.
Source
Thrown at v2/crates/homecore-server/src/plugins.rs:217
let mut loaded: Vec<(PluginId, WasmPlugin)> = Vec::with_capacity(discovered.len());
for package in discovered {
let id = PluginId::new(&package.manifest.domain);
let bytes = package
.read_module(config.limits)
.with_context(|| format!("failed reading plugin `{id}`"))?;
let plugin = runtime
.load_plugin(&package.manifest, &bytes, hc.clone(), &policy)
.with_context(|| format!("plugin `{id}` rejected before setup"))?;
let config_entry = serde_json::to_string(&ConfigEntryJson::bootstrap(id.as_str()))?;
let setup_plugin = plugin.clone();
let result = tokio::task::spawn_blocking(move || setup_plugin.call_setup(&config_entry))
.await
.with_context(|| format!("plugin `{id}` setup task failed"))?
.with_context(|| format!("plugin `{id}` setup trapped"))?;
if result != 0 {
let _ = plugin.call_teardown();
teardown_wasm(loaded).await;
anyhow::bail!("plugin `{id}` setup returned failure code {result}");
}
info!(
plugin = %id,
package = %package.package_dir.display(),
"signed WASM plugin loaded"
);
loaded.push((id, plugin));
}
Ok(loaded)
}
#[cfg(feature = "wasmtime")]
async fn teardown_wasm(plugins: Vec<(PluginId, WasmPlugin)>) {
for (_, plugin) in plugins.into_iter().rev() {
let _ = tokio::task::spawn_blocking(move || plugin.call_teardown()).await;
}
}
View on GitHub (pinned to 4685618388)
Solutions
- Check the plugin's own logs/stdout around setup -- the non-zero code is its failure reason
- Rebuild the plugin against the same homecore-plugins/host version as the server so manifest and ABI match
- Provide the configuration the plugin's setup expects (its bootstrap config entry) before it is loaded
- To get the server up, temporarily move the failing plugin's directory out of the configured plugin dir, fix it, then restore
Example fix
# before ls /etc/homecore/plugins/ # broken-integration/ (setup returns 3 on missing config) ./homecore-server --plugin-dir /etc/homecore/plugins # error: plugin `broken-integration` setup returned failure code 3 # after mv /etc/homecore/plugins/broken-integration /tmp/quarantine/ ./homecore-server # starts with remaining plugins # fix broken-integration setup/config, rebuild the .wasm, move it back
Defensive patterns
Strategy: try-catch
Validate before calling
// preflight (deploy script): validate each plugin package loads+setups before server start // run `homecore-server --plugin-dir <dir> --dry-run-plugins` if available, or load in a scratch // harness first; only promote plugins whose setup exits 0 into the production plugin dir
Try / catch
match load_wasm_plugins(&hc, &config).await {
Ok(plugins) => plugins,
Err(e) if e.to_string().contains("setup returned failure code") => {
tracing::error!("plugin failed setup; quarantining: {e}");
quarantine_last_plugin(&config)?; // move dir aside, continue boot without it
load_wasm_plugins(&hc, &config).await?
}
Err(e) => return Err(e),
} Prevention
- Build plugins from the same homecore-plugins SDK commit as the host runtime
- Exercise plugin setup in CI against a scratch host before shipping artifacts
- Ship each plugin's required config entries alongside its .wasm so bootstrap setup cannot fail on missing values
When it happens
Trigger: A plugin whose setup() rejects its bootstrap config (missing required config entry, invalid values), a plugin built against a different host ABI/manifest version than this homecore-server, or a guest bug (panic trapped into a failure return). The code in {result} is the plugin's own failure reason.
Common situations: Plugins compiled from an older/newer homecore-plugins SDK than the host; required per-plugin configuration not provided before first start; plugin expects capabilities (FS, network) the policy denies; corrupted .wasm artifact.
Related errors
- plugin directories were configured, but homecore-server was
- plugin trust options were configured, but homecore-server wa
- Missing required configuration: {missing_fields}
- sampling_rate must be positive
- buffer_size must be positive
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/bba3c3ddb70f976f.
Report an issue: GitHub.