jdx/mise · error
workspace project {id:?} cannot both add and remove dependen
Error message
workspace project {id:?} cannot both add and remove dependency {dependency:?} What it means
A [monorepo.projects."<id>"] override cannot list the same dependency in both depends_add and depends_remove. validate_override() checks the intersection of the two sets and rejects any overlap, because add+remove of the same edge is contradictory (order of application is depends replacement, then remove, then add, so the intent is ambiguous).
Source
Thrown at src/task/workspace.rs:1166
}
}
fn validate_override(id: &ProjectId, config: &WorkspaceProjectOverride) -> Result<()> {
if config.remove
&& (config.root.is_some()
|| config.metadata.is_some()
|| config.depends.is_some()
|| !config.depends_add.is_empty()
|| !config.depends_remove.is_empty())
{
bail!("removed workspace project {id:?} cannot define other overrides");
}
if let Some(dependency) = config
.depends_add
.intersection(&config.depends_remove)
.next()
{
bail!("workspace project {id:?} cannot both add and remove dependency {dependency:?}");
}
Ok(())
}
fn parse_dependency_ids(
project_id: &ProjectId,
field: &str,
dependencies: &BTreeSet<String>,
) -> Result<BTreeSet<ProjectId>> {
dependencies
.iter()
.map(|dependency| {
dependency.parse::<ProjectId>().map_err(|err| {
eyre::eyre!(
"workspace project {project_id:?} has invalid {field} entry {dependency:?}: {err}"
)
})
})View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Decide the final state: keep the edge only in depends_add, or only in depends_remove
- To replace the whole dependency set, use depends = [...] alone (full replacement) instead of add+remove pairs
- After merge conflicts, grep the entry for the duplicated ID in both lists
Example fix
# before (mise.toml) [monorepo.projects."cargo:app"] depends_add = ["cargo:shared", "cargo:util"] depends_remove = ["cargo:shared"] # after [monorepo.projects."cargo:app"] depends_add = ["cargo:util"]
Defensive patterns
Strategy: validation
Validate before calling
for (raw_id, cfg) in &overrides {
if let Some(dup) = cfg.depends_add.intersection(&cfg.depends_remove).next() {
return Err(eyre::eyre!("entry {raw_id}: {dup} appears in both depends_add and depends_remove"));
}
} Type guard
fn add_remove_are_disjoint(cfg: &WorkspaceProjectOverride) -> bool {
cfg.depends_add.is_disjoint(&cfg.depends_remove)
} Prevention
- Prefer depends = [...] full replacement when rewriting edges — it cannot conflict with itself
- Lint [monorepo.projects] entries in CI (tomlq/jq check for intersection) before commit
- After merge conflicts, deduplicate dependency IDs across both lists
When it happens
Trigger: An override entry where depends_add and depends_remove share an element, e.g. depends_add = ["cargo:shared"], depends_remove = ["cargo:shared"]; usually a typo or an attempt to 'move' an edge that ends up listed on both sides.
Common situations: Editing a long depends_add/depends_remove list during refactor; merge conflict resolution duplicating an entry into both keys; attempting to toggle an edge via two config layers.
Related errors
- removed workspace project {id:?} cannot define other overrid
- version_order must be "source" or "semver"
- absent bootstrap group '{name}' must not set gid or system
- present bootstrap user '{name}' requires a primary group
- present bootstrap user '{name}' must not set remove_home
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/3992c1960c9cf898.
Report an issue: GitHub.