{"record":{"id":"749a694d9efdde8a","repo":"vercel/turborepo","slug":"new-workspace-is-missing-a-package-json-file","errorCode":null,"errorMessage":"New workspace is missing a package.json file","messagePattern":"New workspace is missing a package\\.json file","errorType":"console","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/turbo-gen/src/generators/copy.ts","lineNumber":47,"sourceCode":"    );\n    await createProject({\n      appPath: location.absolute,\n      example: opts.copy.source,\n      examplePath: opts.examplePath\n    });\n\n    try {\n      if (fs.existsSync(newPackageJsonPath)) {\n        const packageJson = (await fs.readJSON(\n          newPackageJsonPath\n        )) as PackageJson;\n        if (packageJson.workspaces) {\n          throw new Error(\n            \"New workspace root detected - unexpected 'workspaces' field in package.json\"\n          );\n        }\n      } else {\n        throw new Error(\"New workspace is missing a package.json file\");\n      }\n\n      if (fs.existsSync(path.join(location.absolute, \"pnpm-workspace.yaml\"))) {\n        throw new Error(\n          \"New workspace root detected - unexpected pnpm-workspace.yaml\"\n        );\n      }\n    } catch (err) {\n      let message = \"UNKNOWN_ERROR\";\n      if (err instanceof Error) {\n        message = err.message;\n      }\n      logger.error(message);\n\n      // rollback changes\n      await fs.rm(location.absolute, { recursive: true, force: true });\n      return;\n    }","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/vercel/turborepo/blob/9f94a7d215b3881942527dd526afa3fc650869d5/packages/turbo-gen/src/generators/copy.ts#L29-L65","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["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)","If the target is not a Node package yet, add a minimal package.json (`{ \"name\": \"...\", \"private\": true }`) to the source and re-run","Verify the path with `ls <source>/package.json` before invoking turbo gen"],"exampleFix":"# before\nturbo gen --copy ~/src/some-repo          # package.json is in ~/src/some-repo/packages/app\n# after\nturbo gen --copy ~/src/some-repo/packages/app","handlingStrategy":"validation","validationCode":"import fs from 'node:fs';\n\nfunction isCopyablePackage(dir: string): boolean {\n  try {\n    JSON.parse(fs.readFileSync(`${dir}/package.json`, 'utf8'));\n    return true;\n  } catch {\n    return false;\n  }\n}\n// require isCopyablePackage(source) before turbo gen --copy <source>","typeGuard":"function hasPackageJson(dir: string): boolean {\n  return fs.existsSync(`${dir}/package.json`);\n}","tryCatchPattern":null,"preventionTips":["Run `ls <source>/package.json` before every scripted --copy invocation","For GitHub sources, point at the sub-directory containing the package, not the repo root","Add a minimal package.json to non-Node projects before copying them in"],"tags":["turbo-gen","workspace","copy","package-json","validation"],"backgroundTag":"missing-package-json","analyzedSha":"9f94a7d215b3881942527dd526afa3fc650869d5","analyzedAt":"2026-08-16T19:47:29.531Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}