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
- Choose a single-package example as the copy source
- If the example is a monorepo, point the example path at one package directory inside it instead of the repository root
- 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
- Copy from single-package examples only, or target a package directory with example path
- Clone the example locally and inspect its package.json before referencing it
- Watch upstream examples for restructuring into monorepos
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
- New workspace root detected - unexpected pnpm-workspace.yaml
- New workspace is missing a package.json file
- Workspace " " not found
- May not specify workspace name in non-root turbo.json
- plop_error_running_generator
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)