{"record":{"id":"9bce99ec55a747eb","repo":"vercel/turborepo","slug":"non-root","errorCode":null,"errorMessage":"non-root","messagePattern":"non-root","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/turborepo-repository/src/discovery.rs","lineNumber":193,"sourceCode":"            return Ok(DiscoveryResponse {\n                workspaces: package_paths\n                    .into_iter()\n                    .map(|package_json| WorkspaceData {\n                        package_json,\n                        turbo_json: None,\n                    })\n                    .collect(),\n                package_manager: self.package_manager.clone(),\n            });\n        }\n\n        // `buffered` keeps discovery order deterministic while letting the\n        // per-workspace turbo.json stats run concurrently — sequentially\n        // these 1-per-workspace syscalls cost ~20ms on large monorepos.\n        futures::stream::iter(package_paths.into_iter().map(|path| async move {\n            let potential_turbo = path\n                .parent()\n                .expect(\"non-root\")\n                .join_component(\"turbo.json\");\n            let potential_turbo_exists = tokio::fs::try_exists(potential_turbo.as_path()).await;\n\n            Ok(WorkspaceData {\n                package_json: path,\n                turbo_json: potential_turbo_exists\n                    .unwrap_or_default()\n                    .then_some(potential_turbo),\n            })\n        }))\n        .buffered(64)\n        .collect::<Vec<Result<WorkspaceData, Error>>>()\n        .instrument(tracing::info_span!(\"turbo_json_stat_stream\"))\n        .await\n        .into_iter()\n        .collect::<Result<Vec<_>, _>>()\n        .map(|workspaces| DiscoveryResponse {\n            workspaces,","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/vercel/turborepo/blob/7fe373bc270adb30db3c184c55069f77feb1a6d6/crates/turborepo-repository/src/discovery.rs#L175-L211","documentation":"During workspace discovery (discovery.rs:169 region), turbo globs package.json files and, per path, joins parent().join_component(\"turbo.json\"). The `.expect(\"non-root\")` panics when a discovered package.json path has no parent — which on a filesystem is only true for the root itself (/package.json or a drive root). In practice it means discovery started scanning at (or matched) the filesystem root.","triggerScenarios":"Workspace discovery producing `/package.json` (Unix) or `C:\\package.json` (Windows) as a candidate — degenerate glob root, running turbo with cwd = filesystem root and a config that makes discovery walk upward to /, or a broken root/workspace glob.","commonSituations":"CI containers whose workdir is / with no project mounted Glob/workspace configuration mistakes (empty or absolute-rooted patterns) Practically never in normal checkouts","solutions":["Run turbo from inside an actual project directory (check `pwd` in CI before the turbo step)","Fix workspace/root configuration so discovery anchors inside the repo, not at /","If a package.json legitimately exists at your filesystem root, move it — it breaks more than turbo","Report the glob config + cwd if the cause is not obvious"],"exampleFix":"# before (CI step)\nworkdir: /\nrun: turbo run build\n# after\nworkdir: /home/runner/work/repo/repo\nrun: turbo run build","handlingStrategy":"validation","validationCode":"// guard discovery inputs: every package.json must have a parent\nfor p in package_paths {\n    if p.parent().is_none() {\n        anyhow::bail!(\"discovery produced root-level package.json: {p}\");\n    }\n}","typeGuard":"fn has_parent(p: &std::path::Path) -> bool { p.parent().map(|x| !x.as_os_str().is_empty()).unwrap_or(false) }","tryCatchPattern":null,"preventionTips":["CI: verify the workdir is the mounted project before running turbo","Never keep package.json at / or drive roots","Sanity-check absolute-rooted glob patterns in workspace config"],"tags":["discovery","workspace","panic","path","root"],"backgroundTag":"package-json-outside-project","analyzedSha":"7fe373bc270adb30db3c184c55069f77feb1a6d6","analyzedAt":"2026-08-17T10:46:15.696Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}