vercel/turborepo · error

non-root

Error message

non-root

What it means

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.

Source

Thrown at crates/turborepo-repository/src/discovery.rs:193

            return Ok(DiscoveryResponse {
                workspaces: package_paths
                    .into_iter()
                    .map(|package_json| WorkspaceData {
                        package_json,
                        turbo_json: None,
                    })
                    .collect(),
                package_manager: self.package_manager.clone(),
            });
        }

        // `buffered` keeps discovery order deterministic while letting the
        // per-workspace turbo.json stats run concurrently — sequentially
        // these 1-per-workspace syscalls cost ~20ms on large monorepos.
        futures::stream::iter(package_paths.into_iter().map(|path| async move {
            let potential_turbo = path
                .parent()
                .expect("non-root")
                .join_component("turbo.json");
            let potential_turbo_exists = tokio::fs::try_exists(potential_turbo.as_path()).await;

            Ok(WorkspaceData {
                package_json: path,
                turbo_json: potential_turbo_exists
                    .unwrap_or_default()
                    .then_some(potential_turbo),
            })
        }))
        .buffered(64)
        .collect::<Vec<Result<WorkspaceData, Error>>>()
        .instrument(tracing::info_span!("turbo_json_stat_stream"))
        .await
        .into_iter()
        .collect::<Result<Vec<_>, _>>()
        .map(|workspaces| DiscoveryResponse {
            workspaces,

View on GitHub (pinned to 7fe373bc27)

Solutions

  1. Run turbo from inside an actual project directory (check `pwd` in CI before the turbo step)
  2. Fix workspace/root configuration so discovery anchors inside the repo, not at /
  3. If a package.json legitimately exists at your filesystem root, move it — it breaks more than turbo
  4. Report the glob config + cwd if the cause is not obvious

Example fix

# before (CI step)
workdir: /
run: turbo run build
# after
workdir: /home/runner/work/repo/repo
run: turbo run build
Defensive patterns

Strategy: validation

Validate before calling

// guard discovery inputs: every package.json must have a parent
for p in package_paths {
    if p.parent().is_none() {
        anyhow::bail!("discovery produced root-level package.json: {p}");
    }
}

Type guard

fn has_parent(p: &std::path::Path) -> bool { p.parent().map(|x| !x.as_os_str().is_empty()).unwrap_or(false) }

Prevention

When it happens

Trigger: 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.

Common situations: CI containers whose workdir is / with no project mounted Glob/workspace configuration mistakes (empty or absolute-rooted patterns) Practically never in normal checkouts

Related errors


AI-assisted analysis of vercel/turborepo@7fe373bc27 (2026-08-17). Data as JSON: /api/errors/9bce99ec55a747eb. Report an issue: GitHub.