{"record":{"id":"160e92269efad1b5","repo":"zeroclaw-labs/zeroclaw","slug":"manifest-missing-tool-name","errorCode":null,"errorMessage":"manifest missing [tool] name","messagePattern":"manifest missing \\[tool\\] name","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-hardware/src/loader.rs","lineNumber":179,"sourceCode":"    })?;\n\n    let manifest: ToolManifest = toml::from_str(&raw).map_err(|e| {\n        ::zeroclaw_log::record!(\n            WARN,\n            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)\n                .with_outcome(::zeroclaw_log::EventOutcome::Failure)\n                .with_attrs(::serde_json::json!({\n                    \"manifest_path\": manifest_path.display().to_string(),\n                    \"error\": format!(\"{}\", e),\n                })),\n            \"hardware plugin manifest failed to parse\"\n        );\n        anyhow::Error::msg(format!(\"TOML parse error in tool.toml: {e}\"))\n    })?;\n\n    // Validate required fields — fail fast with a descriptive error.\n    if manifest.tool.name.trim().is_empty() {\n        anyhow::bail!(\"manifest missing [tool] name\");\n    }\n    if manifest.tool.description.trim().is_empty() {\n        anyhow::bail!(\"manifest missing [tool] description\");\n    }\n    if manifest.exec.binary.trim().is_empty() {\n        anyhow::bail!(\"manifest missing [exec] binary\");\n    }\n\n    // Validate binary path: must exist, be a regular file, and reside within plugin_dir.\n    let canonical_plugin_dir = plugin_dir.canonicalize().map_err(|e| {\n        ::zeroclaw_log::record!(\n            WARN,\n            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)\n                .with_outcome(::zeroclaw_log::EventOutcome::Failure)\n                .with_attrs(::serde_json::json!({\n                    \"plugin_dir\": plugin_dir.display().to_string(),\n                    \"error\": format!(\"{}\", e),\n                })),","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-hardware/src/loader.rs#L161-L197","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-writing a first plugin manifest from memory; copy-pasting a template and trimming lines; renaming sections during refactoring.","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"],"exampleFix":"# before\n[tool]\ndescription = \"Reads sensors\"\n# after\n[tool]\nname = \"read-sensors\"\ndescription = \"Reads sensors\"","handlingStrategy":"validation","validationCode":"// Lint a manifest before handing it to load_one_plugin:\nfn required_fields_ok(m: &ToolManifest) -> Result<(), String> {\n    if m.tool.name.trim().is_empty() {\n        return Err(\"[tool] name is required\".into());\n    }\n    Ok(())\n}","typeGuard":"fn is_valid_tool_manifest(raw: &str) -> bool {\n    let m: Option<ToolManifest> = toml::from_str(raw).ok();\n    m.is_some_and(|m| !m.tool.name.trim().is_empty())\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["hardware","plugin","manifest","toml","loader"],"backgroundTag":"manifest-missing-field","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}