{"record":{"id":"8ccabfa65a620542","repo":"rust-lang/rust-analyzer","slug":"more-than-one-project","errorCode":null,"errorMessage":"more than one project","messagePattern":"more than one project","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/project-model/src/lib.rs","lineNumber":126,"sourceCode":"            return Ok(ProjectManifest::CargoToml(path));\n        }\n        if path.extension().unwrap_or_default() == \"rs\" {\n            return Ok(ProjectManifest::CargoScript(path));\n        }\n        bail!(\n            \"project root must point to a Cargo.toml, rust-project.json or <script>.rs file: {path}\"\n        );\n    }\n\n    pub fn discover_single(path: &AbsPath) -> anyhow::Result<ProjectManifest> {\n        let mut candidates = ProjectManifest::discover(path)?;\n        let res = match candidates.pop() {\n            None => bail!(\"no projects\"),\n            Some(it) => it,\n        };\n\n        if !candidates.is_empty() {\n            bail!(\"more than one project\");\n        }\n        Ok(res)\n    }\n\n    pub fn discover(path: &AbsPath) -> io::Result<Vec<ProjectManifest>> {\n        if let Some(project_json) = find_in_parent_dirs(path, \"rust-project.json\") {\n            return Ok(vec![ProjectManifest::ProjectJson(project_json)]);\n        }\n        if let Some(project_json) = find_in_parent_dirs(path, \".rust-project.json\") {\n            return Ok(vec![ProjectManifest::ProjectJson(project_json)]);\n        }\n        return find_cargo_toml(path)\n            .map(|paths| paths.into_iter().map(ProjectManifest::CargoToml).collect());\n\n        fn find_cargo_toml(path: &AbsPath) -> io::Result<Vec<ManifestPath>> {\n            match find_in_parent_dirs(path, \"Cargo.toml\") {\n                Some(it) => Ok(vec![it]),\n                None => Ok(find_cargo_toml_in_child_dir(read_dir(path)?)),","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/project-model/src/lib.rs#L108-L144","documentation":"discover_single requires that discovery find exactly one project. After popping one candidate, any remaining candidates cause this bail, because the API is meant for an unambiguous single-project root (e.g. a rust-project.json describing one workspace).","triggerScenarios":"Calling `ProjectManifest::discover_single(&abs_path)` where discovery finds multiple manifests — e.g. a directory containing both a rust-project.json and Cargo.toml files, or several candidate manifests in parent/nested dirs.","commonSituations":"Pointing discover_single at a workspace root that also has a rust-project.json and Cargo.toml; monorepo with multiple crate manifests where the caller expected one; leftover rust-project.json from a prior non-Cargo setup.","solutions":["Delete or move the extra manifest (e.g. remove a stale rust-project.json next to Cargo.toml).","Point discover_single at the specific crate's Cargo.toml directory.","Switch to ProjectManifest::discover() and pick the manifest you want programmatically."],"exampleFix":"// before\nlet manifest = ProjectManifest::discover_single(&monorepo_root)?; // ambiguous\n// after\nlet manifest = ProjectManifest::discover_single(&monorepo_root.join(\"crates/mylib\"))?;","handlingStrategy":"validation","validationCode":"// count candidates before requesting a single project\nlet candidates = ProjectManifest::discover(&path)?;\nif candidates.len() != 1 {\n    // pick explicitly: e.g. prefer rust-project.json, or error out with choices\n}","typeGuard":null,"tryCatchPattern":"match ProjectManifest::discover_single(&path) {\n    Ok(m) => m,\n    Err(e) if e.to_string() == \"more than one project\" => {\n        let mut c = ProjectManifest::discover(&path)?;\n        c.retain(|m| matches!(m, ProjectManifest::CargoToml(_)));\n        c.pop().ok_or_else(|| anyhow!(\"no usable manifest\"))?\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Remove stale rust-project.json files when a project moved to Cargo.","Point discover_single at a specific crate directory, not a monorepo root.","Use discover() with explicit selection logic in multi-project workspaces."],"tags":["rust-analyzer","project-model","discovery","ambiguity"],"backgroundTag":"ambiguous-project-root","analyzedSha":"e8f7e90aa3e7b26aa9a000200f606c1078da99ec","analyzedAt":"2026-09-03T21:08:06.959Z","contentChangedAt":"2026-09-03T21:08:06.959Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}