vercel/turborepo · error

New workspace root detected - unexpected 'workspaces' field…

Error message

New workspace root detected - unexpected 'workspaces' field in package.json

What it means

The turbo-gen copy generator copies an external example into your monorepo as a single new workspace. After the copy, it validates that the result is one package, not another monorepo root. It throws this Error when the copied package.json declares a workspaces field, which marks the example as a monorepo root. The catch block logs the message, deletes the copied directory, and aborts.

Solutions

  1. Choose a single-package example as the copy source
  2. If the example is a monorepo, point the example path at one package directory inside it instead of the repository root
  3. If you own the source, remove the workspaces field or publish a single-package variant

Example fix

# before: copying a monorepo example root
npm exec turbo gen -- --copy https://github.com/example/monorepo-root
# after: copy one package from inside it
npm exec turbo gen -- --copy https://github.com/example/monorepo-root --example-path apps/web
Defensive patterns

Strategy: validation

Validate before calling

// inspect a copy source for monorepo markers before running turbo gen
import fs from "node:fs";

function isSinglePackageExample(dir: string): boolean {
  const pkg = JSON.parse(fs.readFileSync(`${dir}/package.json`, "utf8"));
  const hasWorkspaces = Boolean(pkg.workspaces);
  const hasPnpmWorkspace = fs.existsSync(`${dir}/pnpm-workspace.yaml`);
  return !hasWorkspaces && !hasPnpmWorkspace;
}

Type guard

function isWorkspaceRootManifest(pkg: { workspaces?: unknown }): boolean {
  return Boolean(pkg.workspaces);
}

Prevention

When it happens

Trigger: You run turbo gen with a copy source that is itself a monorepo. createProject copies it in, fs.readJSON loads its package.json, packageJson.workspaces is truthy, and the guard throws. The generator rolls back by removing the destination directory.

Common situations: Pointing turbo gen at an official or community example that is a full monorepo rather than a single app. Copying a starter that recently restructured into workspaces. examplePath selecting the root of an example instead of a single package inside it.

Related errors


AI-assisted analysis of vercel/turborepo@f9245100cf (2026-08-17). Data as JSON: /api/errors/96fea68ddd9205cd. Report an issue: GitHub.

Appendix: source

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

  if (opts.copy.type === "external") {
    logger.log();
    logger.warn("Some manual modifications may be required.");
    logger.dimmed(
      `This ${type} may require local dependencies or a different package manager than what is available in this repo`
    );
    await createProject({
      appPath: location.absolute,
      example: opts.copy.source,
      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);

View on GitHub (pinned to f9245100cf)