{"record":{"id":"d7639cd95c779f88","repo":"herdrdev/herdr","slug":"build-command-must-not-be-empty","errorCode":null,"errorMessage":"build command must not be empty","messagePattern":"build command must not be empty","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"src/cli/plugin.rs","lineNumber":1310,"sourceCode":"    }\n    Err(io::Error::other(\n        \"plugin build changed herdr-plugin.toml after install preview; aborting install\",\n    ))\n}\n\nfn run_plugin_build_command(\n    plugin_id: &str,\n    build_index: usize,\n    build_total: usize,\n    cwd: &Path,\n    command: &[String],\n) -> Result<(), Box<PluginBuildFailure>> {\n    let context = plugin_build_context(plugin_id, build_index, build_total, cwd, command);\n    let Some(program) = command.first() else {\n        return Err(Box::new(PluginBuildFailure {\n            context,\n            kind: PluginBuildFailureKind::Start {\n                error: io::Error::new(\n                    io::ErrorKind::InvalidInput,\n                    \"build command must not be empty\",\n                ),\n            },\n        }));\n    };\n    let args = command.iter().skip(1).cloned().collect::<Vec<_>>();\n    let mut child = crate::plugin_command::command_for_argv_in_dir(program, &args, cwd);\n    child\n        .stdin(Stdio::null())\n        .stdout(Stdio::piped())\n        .stderr(Stdio::piped());\n    scrub_herdr_runtime_env(&mut child);\n\n    let mut child = match child.spawn() {\n        Ok(child) => child,\n        Err(err) => {\n            return Err(Box::new(PluginBuildFailure {","sourceCodeStart":1292,"sourceCodeEnd":1328,"githubUrl":"https://github.com/herdrdev/herdr/blob/f457cff4f2648eee85d176f8a41861241d4e8428/src/cli/plugin.rs#L1292-L1328","documentation":"When running a managed plugin's build command, the runner requires a non-empty command vector; command.first() returning None (src/cli/plugin.rs:1310) yields PluginBuildFailureKind::Start with io::ErrorKind::InvalidInput 'build command must not be empty'. This means the plugin manifest or resolved build configuration produced an empty argv.","triggerScenarios":"Building a managed plugin whose manifest declares an empty build command array (e.g. build = [] or build = \"\" split into zero tokens), so the spawned argv has no program element.","commonSituations":"Hand-edited plugin manifests, a plugin spec that omits or blank-initializes the build field while still marking the plugin as needing builds, or templating bugs that strip the command.","solutions":["Fix the plugin manifest so its build command is a non-empty argv, e.g. build = [\"cargo\", \"build\", \"--release\"]","If the plugin should not be built, remove/skip the build configuration instead of leaving it empty","Reinstall the plugin from its source so a well-formed manifest is regenerated"],"exampleFix":"# before (plugin manifest)\nbuild = []\n\n# after\nbuild = [\"cargo\", \"build\", \"--release\"]","handlingStrategy":"validation","validationCode":"if plugin_manifest.build.is_empty() {\n    return Err(\"plugin build command must not be empty\".into());\n}\nrun_plugin_build(&manifest)?;","typeGuard":null,"tryCatchPattern":"match run_plugin_build(...) {\n    Err(e) if matches!(e.kind_str(), \"build command must not be empty\") => fix_manifest(),\n    r => r,\n}","preventionTips":["Validate plugin manifests at load time, not at build time","Use schema-checked manifests with build as a required non-empty array when builds are enabled"],"tags":["plugin","build","manifest-validation","rust"],"backgroundTag":"empty-command-configuration","analyzedSha":"f457cff4f2648eee85d176f8a41861241d4e8428","analyzedAt":"2026-08-28T15:41:09.197Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}