{"record":{"id":"72530a403e1d5e46","repo":"zeroclaw-labs/zeroclaw","slug":"manifest-missing-exec-binary","errorCode":null,"errorMessage":"manifest missing [exec] binary","messagePattern":"manifest missing \\[exec\\] binary","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-hardware/src/loader.rs","lineNumber":185,"sourceCode":"                .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                })),\n            \"cannot canonicalize plugin dir\"\n        );\n        anyhow::Error::msg(format!(\n            \"cannot canonicalize plugin dir {}: {e}\",\n            plugin_dir.display()\n        ))","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-hardware/src/loader.rs#L167-L203","documentation":"Third required-field check in `load_one_plugin`: the `[exec]` section's `binary` value is empty after trimming, so the manifest never names the executable to run for the tool. Existence, containment, and file-type checks come after this, so reaching them at all requires a non-empty `binary` value here.","triggerScenarios":"A `tool.toml` with a complete `[tool]` section but no `[exec]` section, `binary = \"\"`, a whitespace-only value, or the key misnamed (`path`/`cmd` instead of `binary`).","commonSituations":"Manifest authored before the tool binary exists; section named `[executable]` by mistake; key renamed during template editing.","solutions":["Add an `[exec]` section with `binary = \"<path relative to plugin dir>\"`","Check the key is exactly `binary` and the section is exactly `[exec]`","Verify the remaining binary checks pass (exists, inside plugin dir, regular file) after fixing"],"exampleFix":"# before\n[tool]\nname = \"read-sensors\"\ndescription = \"Reads board sensors\"\n# after\n[tool]\nname = \"read-sensors\"\ndescription = \"Reads board sensors\"\n\n[exec]\nbinary = \"bin/read-sensors\"","handlingStrategy":"validation","validationCode":"fn required_fields_ok(m: &ToolManifest) -> Result<(), String> {\n    if m.exec.binary.trim().is_empty() {\n        return Err(\"[exec] binary is required\".into());\n    }\n    Ok(())\n}","typeGuard":"fn manifest_has_exec_binary(raw: &str) -> bool {\n    toml::from_str::<ToolManifest>(raw)\n        .map(|m| !m.exec.binary.trim().is_empty())\n        .unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Use the exact key `binary` under the exact section `[exec]` — synonyms like path or cmd silently default to empty","Author the manifest next to the binary so the exec section is never an afterthought","Validate all three required fields (name, description, binary) in one lint 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"}