{"record":{"id":"8d241ba1f01c9c76","repo":"jdx/mise","slug":"workspace-provider-id-value-cannot-contain","errorCode":null,"errorMessage":"workspace provider ID {value:?} cannot contain ':'","messagePattern":"workspace provider ID (.+?) cannot contain ':'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/task/workspace.rs","lineNumber":73,"sourceCode":"    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.\n    pub root: PathBuf,\n    /// Provider-neutral facts that consumers may use for inspection or inference.\n    pub metadata: BTreeMap<String, String>,\n    /// Projects that this project directly depends on.\n    pub dependencies: BTreeSet<ProjectId>,\n    /// Provider and metadata source that inferred this project.\n    pub provenance: WorkspaceProvenance,\n    /// Provider attribution for each inferred dependency edge.","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/task/workspace.rs#L55-L91","documentation":"Because workspace project IDs are namespaced as `provider:local`, the provider part itself must not contain a colon, or the namespace would be ambiguous. `validate_id_part` enforces this only for `kind == \"provider\"` and fails with the offending value quoted.","triggerScenarios":"Calling `WorkspaceProject::new(\"my:provider\", local_id)` or registering a workspace provider whose `id()` contains `:`, e.g. copied from an already-namespaced project ID.","commonSituations":"A user pastes a full project ID like `npm:web` into a provider-name config field; a provider derives its ID from a URL or scoped package name containing `:`.","solutions":["Use a colon-free provider name (e.g. `npm` instead of `npm:`)","Strip any namespace prefix before constructing the provider ID","If the value came from a full project ID, split on `:` and use only the provider part"],"exampleFix":"// before\nWorkspaceProject::new(\"npm:frontend\", \"web\")\n// after\nWorkspaceProject::new(\"npm\", \"web\")","handlingStrategy":"validation","validationCode":"if provider.contains(':') {\n    return Err(anyhow!(\"provider ID must not contain ':'\"));\n}\nWorkspaceProject::new(provider, local_id)?;","typeGuard":"fn is_provider_id(s: &str) -> bool { !s.is_empty() && !s.contains(':') && s.trim() == s }","tryCatchPattern":"match WorkspaceProject::new(provider, local_id) {\n    Ok(p) => p,\n    Err(e) if e.to_string().contains(\"cannot contain ':'\") => {\n        let (prov, rest) = provider.split_once(':').unwrap();\n        WorkspaceProject::new(prov, rest)?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep provider names and project IDs as separate config fields","Never store full namespaced IDs in provider-name fields","Document the `provider:local` ID convention where provider IDs are configured"],"tags":["workspace","validation","identifier"],"backgroundTag":"invalid-identifier-format","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"}