jdx/mise · error · eyre::Report

workspace provider {provider_id:?} returned duplicate projec

Error message

workspace provider {provider_id:?} returned duplicate project ID {id:?}

What it means

While folding provider results into WorkspaceProjectGraph, each discovered project is inserted into a map keyed by its full ProjectId; if the same id is already present the second insert fails with this error. It means a single provider returned two distinct projects whose ecosystem-level identity (package name, module path) collides within one provider namespace.

Source

Thrown at src/task/workspace.rs:664

                    provider_errors.insert(provider_id, error);
                    continue;
                }
                Err(error) => return Err(error),
            };
            for mut project in discovered {
                let expected_prefix = format!("{provider_id}:");
                let Some(local_id) = project.id.as_str().strip_prefix(&expected_prefix) else {
                    bail!(
                        "workspace provider {provider_id:?} returned project ID {:?}; IDs must use the {expected_prefix:?} namespace",
                        project.id
                    );
                };
                validate_id_part("project", local_id)?;
                project.root = normalize_project_root(&project.id, &project.root)?;
                attach_provider_provenance(&mut project, &provider_id);
                let id = project.id.clone();
                if projects.insert(id.clone(), project).is_some() {
                    bail!(
                        "workspace provider {provider_id:?} returned duplicate project ID {id:?}"
                    );
                }
            }
        }

        Ok(Self {
            projects,
            provider_errors,
        })
    }

    /// Applies explicit project and dependency changes after provider discovery.
    pub(crate) fn with_overrides(
        mut self,
        overrides: &BTreeMap<String, WorkspaceProjectOverride>,
    ) -> Result<Self> {
        let mut removed = BTreeSet::new();

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Rename one of the colliding packages (Cargo.toml [package] name) or module paths (go.mod module directive) so ids become unique
  2. If one copy is dead code, exclude its directory from Cargo [workspace] members/exclude or drop it from go.work use
  3. Run `cargo metadata` or `go work sync` first to confirm the toolchain itself also sees the duplicate
  4. If both projects are legitimately distinct, give the second one a distinct ecosystem name rather than trying to alias the id

Example fix

# before: crates/old-core/Cargo.toml and crates/new-core/Cargo.toml both have
[package]
name = "core"

# after (crates/new-core/Cargo.toml)
[package]
name = "new-core"
# update any [monorepo.projects."cargo:core"] override key to "cargo:new-core"
Defensive patterns

Strategy: try-catch

Validate before calling

let mut seen = std::collections::BTreeSet::new();
for project in provider.discover(root)? {
    if !seen.insert(project.id.as_str().to_string()) {
        // two ecosystem entries share this id; rename one before building the graph
        return Err(eyre::eyre!("duplicate id {} discovered", project.id));
    }
}

Type guard

fn has_unique_ids(projects: &[WorkspaceProject]) -> bool {
    let mut seen = std::collections::BTreeSet::new();
    projects.iter().all(|p| seen.insert(p.id.as_str().to_string()))
}

Try / catch

// after catching the eyre::Report from graph construction:
let msg = report.to_string();
if msg.contains("duplicate project ID") {
    // extract the id and point the user at the two same-named packages/modules
    report_project_duplicate(&msg);
}

Prevention

When it happens

Trigger: Two crates in one Cargo workspace declaring the same [package] name (both matched by the members glob); two directories in a go.work use list whose go.mod files declare the same module path; a leftover old directory plus its renamed copy both matching "crates/*" members.

Common situations: Copy-pasted crate scaffolding that kept the original package name; a monorepo refactor that renamed a directory but not its module path; vendored forks with duplicate module paths; merging two workspaces together.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/048640f364ccd981. Report an issue: GitHub.