vercel/turborepo · error · Error

New workspace root detected - unexpected pnpm-workspace.yaml

Error message

New workspace root detected - unexpected pnpm-workspace.yaml

What it means

The other `turbo gen --copy` post-copy guard: a pnpm-workspace.yaml at the copied root marks the source as a pnpm monorepo root, which cannot be nested inside your monorepo as a single workspace. The check runs after the package.json checks; on failure the copy is logged and rolled back (directory recursively removed).

Source

Thrown at packages/turbo-gen/src/generators/copy.ts:51

      examplePath: opts.examplePath
    });

    try {
      if (fs.existsSync(newPackageJsonPath)) {
        const packageJson = (await fs.readJSON(
          newPackageJsonPath
        )) as PackageJson;
        if (packageJson.workspaces) {
          throw new Error(
            "New workspace root detected - unexpected 'workspaces' field in package.json"
          );
        }
      } else {
        throw new Error("New workspace is missing a package.json file");
      }

      if (fs.existsSync(path.join(location.absolute, "pnpm-workspace.yaml"))) {
        throw new Error(
          "New workspace root detected - unexpected pnpm-workspace.yaml"
        );
      }
    } catch (err) {
      let message = "UNKNOWN_ERROR";
      if (err instanceof Error) {
        message = err.message;
      }
      logger.error(message);

      // rollback changes
      await fs.rm(location.absolute, { recursive: true, force: true });
      return;
    }
  } else if (source) {
    const filterFunc: CopyFilterAsync = async (src) =>
      !src.includes("node_modules");

View on GitHub (pinned to 9f94a7d215)

Solutions

  1. Copy the individual workspace package from the pnpm monorepo (the sub-directory with its own package.json and no pnpm-workspace.yaml)
  2. If the file is a leftover from an abandoned pnpm setup in a single-package repo, delete pnpm-workspace.yaml from the source and re-run
  3. For whole-monorepo adoption, migrate each package separately or do a manual move plus workspace-glob registration

Example fix

# before
turbo gen --copy ~/src/pnpm-monorepo      # root contains pnpm-workspace.yaml
# after
turbo gen --copy ~/src/pnpm-monorepo/packages/ui
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs';
import path from 'node:path';

function isPnpmMonorepoRoot(dir: string): boolean {
  return fs.existsSync(path.join(dir, 'pnpm-workspace.yaml'));
}
// reject isPnpmMonorepoRoot(source) before turbo gen --copy <source>

Type guard

function isWorkspaceRootMarker(dir: string): boolean {
  return fs.existsSync(path.join(dir, 'pnpm-workspace.yaml'));
}

Prevention

When it happens

Trigger: Passing --copy a directory that contains a pnpm-workspace.yaml file at its root — i.e. the root of a pnpm-based monorepo rather than one of its workspace packages.

Common situations: Absorbing a pnpm-managed repository by copying its root; a leftover pnpm-workspace.yaml in a repo that no longer uses pnpm workspaces.

Related errors


AI-assisted analysis of vercel/turborepo@9f94a7d215 (2026-08-16). Data as JSON: /api/errors/c06a4429cfcce9b7. Report an issue: GitHub.