{"record":{"id":"a7640de42038990e","repo":"jdx/mise","slug":"duplicate-workspace-provider-id-provider-id","errorCode":null,"errorMessage":"duplicate workspace provider ID {provider_id:?}","messagePattern":"duplicate workspace provider ID (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/task/workspace.rs","lineNumber":630,"sourceCode":"        Ok(graph)\n    }\n\n    fn collect_provider_projects(\n        providers: &[&dyn WorkspaceProvider],\n        workspace_root: &Path,\n        context: &WorkspaceDiscoveryContext,\n        skip_provider_errors: bool,\n    ) -> Result<WorkspaceProjectGraph> {\n        let mut providers = providers\n            .iter()\n            .map(|provider| (provider.id().to_string(), *provider))\n            .collect::<Vec<_>>();\n        providers.sort_by(|(left, _), (right, _)| left.cmp(right));\n\n        for (index, (provider_id, _)) in providers.iter().enumerate() {\n            validate_id_part(\"provider\", provider_id)?;\n            if index > 0 && providers[index - 1].0 == *provider_id {\n                bail!(\"duplicate workspace provider ID {provider_id:?}\");\n            }\n        }\n\n        let mut projects = BTreeMap::new();\n        let mut provider_errors = BTreeMap::new();\n        for (provider_id, provider) in providers {\n            let discovered = match provider.discover_with_context(workspace_root, context) {\n                Ok(projects) => projects,\n                Err(error) if skip_provider_errors => {\n                    let error = format!(\"{error:#}\");\n                    warn!(\n                        \"failed to discover {provider_id} workspace projects at {}; inferred tasks \\\n                         and upstream task dependencies from this provider are unavailable: {error}\",\n                        workspace_root.display(),\n                    );\n                    provider_errors.insert(provider_id, error);\n                    continue;\n                }","sourceCodeStart":612,"sourceCodeEnd":648,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/task/workspace.rs#L612-L648","documentation":"mise's workspace loader validates that every workspace provider has a unique ID before collecting the projects each provider discovers. After sorting providers by ID, adjacent entries with the same ID indicate the configuration registered the same provider twice. The library bails out during workspace construction rather than silently merging or shadowing providers.","triggerScenarios":"Building/refreshing a Workspace when the collection of (provider_id, provider) pairs contains two entries whose provider IDs are equal, e.g. two workspace providers declared with the same id in config.","commonSituations":"Copy-pasting a provider block in a mise.toml workspace config and forgetting to change its id; merging config files that each register a provider with the same id; tooling generating provider entries programmatically that collides on id.","solutions":["Find the two provider entries with the same ID in your workspace config and rename one so every provider ID is unique.","If config is generated/merged, deduplicate provider entries before writing the config file.","Run `mise doctor` / check the rendered workspace config to confirm which providers are registered and their IDs."],"exampleFix":"// before (mise.toml)\n[[workspace.providers]]\nid = \"monorepo\"\n[[workspace.providers]]\nid = \"monorepo\"\n\n// after\n[[workspace.providers]]\nid = \"monorepo\"\n[[workspace.providers]]\nid = \"vendor\"","handlingStrategy":"validation","validationCode":"let ids: Vec<_> = config.workspace_providers.iter().map(|p| p.id.clone()).collect();\nif ids.len() != ids.iter().collect::<std::collections::BTreeSet<_>>().len() {\n    return Err(\"duplicate workspace provider IDs in config\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give each provider block a distinct, descriptive ID.","Lint generated/merged workspace config for duplicate provider IDs before applying it.","Keep provider definitions in one place to avoid accidental re-registration."],"tags":["workspace","config","duplicate-id","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}