zeroclaw-labs/zeroclaw · error
manifest missing [tool] name
Error message
manifest missing [tool] name
What it means
Plugin manifests (`tool.toml`) are TOML-parsed into a struct where missing string fields default to empty, then `load_one_plugin` validates required fields and names the exact section and field that is absent. This one means the `[tool]` section has no non-empty `name` — missing, empty, or whitespace-only (validation trims). The plugin is rejected with a descriptive error instead of loading half-configured.
Source
Thrown at crates/zeroclaw-hardware/src/loader.rs:179
})?;
let manifest: ToolManifest = toml::from_str(&raw).map_err(|e| {
::zeroclaw_log::record!(
WARN,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)
.with_outcome(::zeroclaw_log::EventOutcome::Failure)
.with_attrs(::serde_json::json!({
"manifest_path": manifest_path.display().to_string(),
"error": format!("{}", e),
})),
"hardware plugin manifest failed to parse"
);
anyhow::Error::msg(format!("TOML parse error in tool.toml: {e}"))
})?;
// Validate required fields — fail fast with a descriptive error.
if manifest.tool.name.trim().is_empty() {
anyhow::bail!("manifest missing [tool] name");
}
if manifest.tool.description.trim().is_empty() {
anyhow::bail!("manifest missing [tool] description");
}
if manifest.exec.binary.trim().is_empty() {
anyhow::bail!("manifest missing [exec] binary");
}
// Validate binary path: must exist, be a regular file, and reside within plugin_dir.
let canonical_plugin_dir = plugin_dir.canonicalize().map_err(|e| {
::zeroclaw_log::record!(
WARN,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)
.with_outcome(::zeroclaw_log::EventOutcome::Failure)
.with_attrs(::serde_json::json!({
"plugin_dir": plugin_dir.display().to_string(),
"error": format!("{}", e),
})),View on GitHub (pinned to 88bb9c8533)
Solutions
- Add `name = "my-tool"` under the `[tool]` section in the plugin's tool.toml
- Confirm the section header is exactly `[tool]` (singular)
- Fix the other required fields flagged next (`[tool] description`, `[exec] binary`) in the same edit
Example fix
# before [tool] description = "Reads sensors" # after [tool] name = "read-sensors" description = "Reads sensors"
Defensive patterns
Strategy: validation
Validate before calling
// Lint a manifest before handing it to load_one_plugin:
fn required_fields_ok(m: &ToolManifest) -> Result<(), String> {
if m.tool.name.trim().is_empty() {
return Err("[tool] name is required".into());
}
Ok(())
} Type guard
fn is_valid_tool_manifest(raw: &str) -> bool {
let m: Option<ToolManifest> = toml::from_str(raw).ok();
m.is_some_and(|m| !m.tool.name.trim().is_empty())
} Prevention
- Start every plugin from a checked-in tool.toml template containing all required fields
- Run a manifest linter over plugin dirs in CI so empty fields fail the build, not the loader
- Treat loader field errors as authoring feedback: fix name, description, and exec binary in one pass
When it happens
Trigger: A `tool.toml` whose `[tool]` section lacks `name`, sets `name = ""`, or sets a whitespace-only value; the section header misspelled as `[tools]` so the field never lands in the struct.
Common situations: Hand-writing a first plugin manifest from memory; copy-pasting a template and trimming lines; renaming sections during refactoring.
Related errors
- manifest missing [tool] description
- manifest missing [exec] binary
- manifest exec binary not found: {}
- manifest exec binary escapes plugin directory: {} is not und
- manifest exec binary is not a regular file: {}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/160e92269efad1b5.
Report an issue: GitHub.