jdx/mise · error
duplicate workspace provider ID
Error message
duplicate workspace provider ID {provider_id:?} What it means
When collecting workspace projects, mise gathers providers into a map and sorts them by ID; this error fires if two entries share the same provider ID after validation. It guards an internal invariant: each provider should appear exactly once, so duplicates indicate a misconfigured or buggy provider registry.
Solutions
- Remove the duplicate provider declaration, keeping one
- Check for the same provider defined in both global (~/.config/mise/config.toml) and project mise.toml and deduplicate
- If the ID comes from config keys, look for aliases resolving to the same underlying provider ID
Example fix
// before providers = ["npm", "npm"] // after providers = ["npm"]
Defensive patterns
Strategy: validation
Validate before calling
let mut seen = std::collections::HashSet::new();
for id in provider_ids {
if !seen.insert(id) {
return Err(anyhow!("duplicate provider id {id}"));
}
} Try / catch
match collect_providers(config) {
Ok(p) => p,
Err(e) if e.to_string().contains("duplicate workspace provider ID") => {
eprintln!("dedupe provider declarations across config files");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Keep provider declarations in exactly one config file
- Inspect layered config sources to find duplicate definitions
- Use a set/map keyed by provider ID when registering providers programmatically
When it happens
Trigger: Registering the same provider ID twice in the workspace provider list, e.g. the same provider name declared in multiple config sources or a provider added twice programmatically.
Common situations: Duplicate provider entries across global and project mise.toml; a plugin listed under two names that resolve to the same ID; repeated registration during config layering.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- workspace provider returned duplicate project ID
- workspace provider attributed lockfile to foreign project
- workspace provider attributed lockfile to unknown project
- workspace provider returned project ID ; IDs must use the…
- affected project exists in graph
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/a7640de42038990e.
Report an issue: GitHub.
Appendix: source
Thrown at src/task/workspace.rs:630
Ok(graph)
}
fn collect_provider_projects(
providers: &[&dyn WorkspaceProvider],
workspace_root: &Path,
context: &WorkspaceDiscoveryContext,
skip_provider_errors: bool,
) -> Result<WorkspaceProjectGraph> {
let mut providers = providers
.iter()
.map(|provider| (provider.id().to_string(), *provider))
.collect::<Vec<_>>();
providers.sort_by(|(left, _), (right, _)| left.cmp(right));
for (index, (provider_id, _)) in providers.iter().enumerate() {
validate_id_part("provider", provider_id)?;
if index > 0 && providers[index - 1].0 == *provider_id {
bail!("duplicate workspace provider ID {provider_id:?}");
}
}
let mut projects = BTreeMap::new();
let mut provider_errors = BTreeMap::new();
for (provider_id, provider) in providers {
let discovered = match provider.discover_with_context(workspace_root, context) {
Ok(projects) => projects,
Err(error) if skip_provider_errors => {
let error = format!("{error:#}");
warn!(
"failed to discover {provider_id} workspace projects at {}; inferred tasks \
and upstream task dependencies from this provider are unavailable: {error}",
workspace_root.display(),
);
provider_errors.insert(provider_id, error);
continue;
}View on GitHub (pinned to 533346cc37)