vercel/turborepo · error · Error

New workspace is missing a package.json file

Error message

New workspace is missing a package.json file

What it means

After `turbo gen --copy` copies the source directory, turbo-gen requires a package.json at the new workspace root — it defines the workspace's identity for prompts and dependency wiring. If fs.existsSync(newPackageJsonPath) is false, this Error is thrown, logged, and the copy is rolled back with a recursive rm.

Source

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

    );
    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);

      // rollback changes
      await fs.rm(location.absolute, { recursive: true, force: true });
      return;
    }

View on GitHub (pinned to 9f94a7d215)

Solutions

  1. Point --copy at the directory that actually contains the package.json (check the error log — the message printed is the destination path that was verified)
  2. If the target is not a Node package yet, add a minimal package.json (`{ "name": "...", "private": true }`) to the source and re-run
  3. Verify the path with `ls <source>/package.json` before invoking turbo gen

Example fix

# before
turbo gen --copy ~/src/some-repo          # package.json is in ~/src/some-repo/packages/app
# after
turbo gen --copy ~/src/some-repo/packages/app
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs';

function isCopyablePackage(dir: string): boolean {
  try {
    JSON.parse(fs.readFileSync(`${dir}/package.json`, 'utf8'));
    return true;
  } catch {
    return false;
  }
}
// require isCopyablePackage(source) before turbo gen --copy <source>

Type guard

function hasPackageJson(dir: string): boolean {
  return fs.existsSync(`${dir}/package.json`);
}

Prevention

When it happens

Trigger: The --copy source directory contains no package.json: a docs folder, a non-Node project, or a repo whose package.json lives one level deeper than the path you passed (examplePath pointing at the wrong sub-directory).

Common situations: Copying a GitHub repo root when the actual package is in a subfolder (e.g. examples/); copying non-JavaScript projects; typos in the copy path that silently resolve to a sibling directory.

Related errors


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