{"record":{"id":"3992c1960c9cf898","repo":"jdx/mise","slug":"workspace-project-id-cannot-both-add-and-remov","errorCode":null,"errorMessage":"workspace project {id:?} cannot both add and remove dependency {dependency:?}","messagePattern":"workspace project (.+?) cannot both add and remove dependency (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/task/workspace.rs","lineNumber":1166,"sourceCode":"    }\n}\n\nfn validate_override(id: &ProjectId, config: &WorkspaceProjectOverride) -> Result<()> {\n    if config.remove\n        && (config.root.is_some()\n            || config.metadata.is_some()\n            || config.depends.is_some()\n            || !config.depends_add.is_empty()\n            || !config.depends_remove.is_empty())\n    {\n        bail!(\"removed workspace project {id:?} cannot define other overrides\");\n    }\n    if let Some(dependency) = config\n        .depends_add\n        .intersection(&config.depends_remove)\n        .next()\n    {\n        bail!(\"workspace project {id:?} cannot both add and remove dependency {dependency:?}\");\n    }\n    Ok(())\n}\n\nfn parse_dependency_ids(\n    project_id: &ProjectId,\n    field: &str,\n    dependencies: &BTreeSet<String>,\n) -> Result<BTreeSet<ProjectId>> {\n    dependencies\n        .iter()\n        .map(|dependency| {\n            dependency.parse::<ProjectId>().map_err(|err| {\n                eyre::eyre!(\n                    \"workspace project {project_id:?} has invalid {field} entry {dependency:?}: {err}\"\n                )\n            })\n        })","sourceCodeStart":1148,"sourceCodeEnd":1184,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/task/workspace.rs#L1148-L1184","documentation":"A workspace project's depends_add and depends_remove override sets must be disjoint. If the same dependency id appears in both, mise cannot determine the final dependency set and throws this error naming the project and the conflicting dependency.","triggerScenarios":"Config for project {id} lists dependency {dependency} under both depends_add and depends_remove; caught during project config validation.","commonSituations":"Layered config files (global + local) each adding and removing the same dependency; copy-paste edits appending to both lists.","solutions":["Remove the dependency from depends_remove if the intent is to add it","Remove the dependency from depends_add if the intent is to drop it","If base config declares it and you want it removed, delete the matching depends_add entry"],"exampleFix":"# before\n[workspace.project.app]\ndepends_add = [\"util\"]\ndepends_remove = [\"util\"]\n# after\n[workspace.project.app]\ndepends_add = [\"util\"]","handlingStrategy":"validation","validationCode":"fn disjoint_depends(cfg: &ProjectConfig) -> Result<(), String> {\n    let clash: Vec<_> = cfg.depends_add.intersection(&cfg.depends_remove).collect();\n    if !clash.is_empty() {\n        return Err(format!(\"depends_add and depends_remove overlap: {clash:?}\"));\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = validate_project_config(&cfg) {\n    if e.to_string().contains(\"cannot both add and remove\") {\n        eprintln!(\"resolve add/remove conflict, then re-validate\");\n    }\n}","preventionTips":["Decide per dependency whether the override adds or removes it; never write it in both sets","When layering configs, merge depends_add/depends_remove and check intersection before saving","Avoid copy-pasting entries between the two lists"],"tags":["workspace","config","dependency-graph"],"backgroundTag":"mutually-exclusive-options","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"}