{"record":{"id":"77b888bdd2560977","repo":"Kuberwastaken/claurst","slug":"plugin-name-cannot-be-empty","errorCode":null,"errorMessage":"Plugin name cannot be empty","messagePattern":"Plugin name cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-rust/crates/plugins/src/manifest.rs","lineNumber":344,"sourceCode":"        let v: serde_json::Value = serde_json::from_slice(bytes)?;\n        // Handle both `mcpServers` (object) and `mcp_servers` (array) keys.\n        let manifest = serde_json::from_value::<PluginManifest>(normalize_manifest_json(v))?;\n        manifest.validate()?;\n        Ok(manifest)\n    }\n\n    /// Parse a manifest from TOML bytes (plugin.toml).\n    pub fn from_toml(bytes: &[u8]) -> anyhow::Result<Self> {\n        let s = std::str::from_utf8(bytes)?;\n        let manifest: PluginManifest = toml::from_str(s)?;\n        manifest.validate()?;\n        Ok(manifest)\n    }\n\n    /// Basic validation matching the TS schema checks.\n    pub fn validate(&self) -> anyhow::Result<()> {\n        if self.name.is_empty() {\n            anyhow::bail!(\"Plugin name cannot be empty\");\n        }\n        if self.name.contains(' ') {\n            anyhow::bail!(\n                \"Plugin name '{}' cannot contain spaces. Use kebab-case.\",\n                self.name\n            );\n        }\n        Ok(())\n    }\n}\n\n/// Normalise the raw JSON value so that both camelCase and snake_case\n/// variants of known fields work, and so `mcpServers` (object mapping) is\n/// converted to a `Vec<PluginMcpServer>`.\nfn normalize_manifest_json(mut v: serde_json::Value) -> serde_json::Value {\n    let obj = match v.as_object_mut() {\n        Some(o) => o,\n        None => return v,","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/plugins/src/manifest.rs#L326-L362","documentation":"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.","triggerScenarios":"Calling PluginManifest::validate (typically via from_toml) on a manifest whose name field is the empty string.","commonSituations":"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.","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"],"exampleFix":"// before (plugin.toml)\nname = \"\"\n// after\nname = \"my-plugin\"","handlingStrategy":"validation","validationCode":"fn manifest_name_ok(m: &PluginManifest) -> bool { !m.name.is_empty() }","typeGuard":null,"tryCatchPattern":"match PluginManifest::from_toml(&toml_str) {\n    Err(e) if e.to_string().contains(\"name cannot be empty\") => { /* prompt for a name */ }\n    other => other?,\n}","preventionTips":["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"],"tags":["plugins","manifest","validation"],"backgroundTag":"empty-required-field","analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}