Kuberwastaken/claurst · error
Plugin name cannot be empty
Error message
Plugin name cannot be empty
What it means
Sentinel validation error from PluginManifest::validate: the parsed plugin manifest (from plugin.json or plugin.toml) has an empty `name` field, i.e. the file is missing a name or declares name = "". Fired after successful deserialization, so the file itself was syntactically valid.
Solutions
- Set a non-empty name in the plugin manifest file
- Use kebab-case for the name (lowercase words separated by hyphens) to also pass the spaces check
- Re-run plugin loading after editing the manifest
Example fix
// before (plugin.toml) name = "" // after name = "my-plugin"
Defensive patterns
Strategy: validation
Validate before calling
fn manifest_name_ok(m: &PluginManifest) -> bool { !m.name.is_empty() } Try / catch
match PluginManifest::from_toml(&toml_str) {
Err(e) if e.to_string().contains("name cannot be empty") => { /* prompt for a name */ }
other => other?,
} Prevention
- Fill in every field of plugin.toml templates before shipping
- Validate manifests in CI with PluginManifest::from_toml + validate
- Use kebab-case names from the start
When it happens
Trigger: Calling PluginManifest::validate (typically via from_toml) on a manifest whose name field is the empty string.
Common situations: Manually created plugin.toml with the name key omitted (if it defaults to empty) or left blank; a code generator emitted an empty name; template file not filled in.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Plugin name ' ' cannot contain spaces. Use kebab-case.
- Invalid env-var format
- source settings.json must be a JSON object
- mcpServers must be an object
- mcpServers. must be an object
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/77b888bdd2560977.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/plugins/src/manifest.rs:344
let v: serde_json::Value = serde_json::from_slice(bytes)?;
// Handle both `mcpServers` (object) and `mcp_servers` (array) keys.
let manifest = serde_json::from_value::<PluginManifest>(normalize_manifest_json(v))?;
manifest.validate()?;
Ok(manifest)
}
/// Parse a manifest from TOML bytes (plugin.toml).
pub fn from_toml(bytes: &[u8]) -> anyhow::Result<Self> {
let s = std::str::from_utf8(bytes)?;
let manifest: PluginManifest = toml::from_str(s)?;
manifest.validate()?;
Ok(manifest)
}
/// Basic validation matching the TS schema checks.
pub fn validate(&self) -> anyhow::Result<()> {
if self.name.is_empty() {
anyhow::bail!("Plugin name cannot be empty");
}
if self.name.contains(' ') {
anyhow::bail!(
"Plugin name '{}' cannot contain spaces. Use kebab-case.",
self.name
);
}
Ok(())
}
}
/// Normalise the raw JSON value so that both camelCase and snake_case
/// variants of known fields work, and so `mcpServers` (object mapping) is
/// converted to a `Vec<PluginMcpServer>`.
fn normalize_manifest_json(mut v: serde_json::Value) -> serde_json::Value {
let obj = match v.as_object_mut() {
Some(o) => o,
None => return v,View on GitHub (pinned to b0637c97ec)