{"record":{"id":"62dd66dd8fe9e127","repo":"jdx/mise","slug":"workspace-kind-id-cannot-be-empty","errorCode":null,"errorMessage":"workspace {kind} ID cannot be empty","messagePattern":"workspace (.+?) ID cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/task/workspace.rs","lineNumber":65,"sourceCode":"    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        Display::fmt(&self.0, f)\n    }\n}\n\nimpl FromStr for ProjectId {\n    type Err = eyre::Report;\n\n    fn from_str(value: &str) -> Result<Self> {\n        let Some((provider, local_id)) = value.split_once(':') else {\n            bail!(\"workspace project ID {value:?} must include a provider namespace\");\n        };\n        Self::new(provider, local_id)\n    }\n}\n\nfn validate_id_part(kind: &str, value: &str) -> Result<()> {\n    if value.is_empty() {\n        bail!(\"workspace {kind} ID cannot be empty\");\n    }\n    if value.trim() != value || value.chars().any(char::is_control) {\n        bail!(\n            \"workspace {kind} ID {value:?} contains surrounding whitespace or control characters\"\n        );\n    }\n    if kind == \"provider\" && value.contains(':') {\n        bail!(\"workspace provider ID {value:?} cannot contain ':'\");\n    }\n    Ok(())\n}\n\n/// A project discovered from ecosystem-specific workspace metadata.\n#[derive(Clone, Debug, Eq, PartialEq, Serialize)]\npub(crate) struct WorkspaceProject {\n    /// Stable identity used by dependency edges and task scoping.\n    pub id: ProjectId,\n    /// Normalized path relative to the workspace root. `.` represents the root.","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/task/workspace.rs#L47-L83","documentation":"This error is thrown by `validate_id_part` in src/task/workspace.rs when an identifier component (provider or project) of a workspace ID is an empty string. Workspace project IDs are namespaced like `provider:local`, and every part must be non-empty to keep IDs unambiguous. The library fails fast instead of creating a workspace entry with an unusable ID.","triggerScenarios":"Calling `WorkspaceProject::new(provider, local_id)` (or a provider's `collect_provider_projects`) with an empty provider name or empty local project ID, e.g. from an empty key/value in workspace config metadata.","commonSituations":"A `[workspace]` TOML section or provider metadata omits the project name; an environment variable or config key resolves to empty; a provider plugin returns a project with an unset ID field.","solutions":["Provide a non-empty provider and project ID when constructing the workspace project","Check the workspace config file / provider metadata for a missing or empty name field","If an env var feeds the ID, verify it is actually set before use"],"exampleFix":"// before\nlet project = WorkspaceProject::new(provider, \"\");\n// after\nlet project = WorkspaceProject::new(provider, \"api-server\");","handlingStrategy":"validation","validationCode":"if provider.is_empty() || local_id.is_empty() {\n    return Err(anyhow!(\"workspace provider/project ID must be non-empty\"));\n}\nlet project = WorkspaceProject::new(provider, local_id)?;","typeGuard":"fn is_valid_id_part(s: &str) -> bool { !s.is_empty() && s.trim() == s && !s.chars().any(char::is_control) }","tryCatchPattern":"match WorkspaceProject::new(provider, local_id) {\n    Ok(p) => p,\n    Err(e) if e.to_string().contains(\"cannot be empty\") => { /* supply a real ID or skip */ }\n    Err(e) => return Err(e),\n}","preventionTips":["Always derive IDs from non-empty config values with defaults","Validate config fields at parse time before constructing workspace objects","Use Option types for optional names so emptiness is explicit"],"tags":["workspace","validation","empty-id"],"backgroundTag":"empty-required-field","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}