vercel/turborepo · error · TransformError

Unable to write package.json

Error message

Unable to write package.json

What it means

After patching the starter's package.json (project name, pinned turbo version), the official-starter transform writes it back with fs.writeJsonSync. It throws this TransformError when the write fails. Common causes are permission errors, a read-only file or directory, a full disk, or a file lock held by another process.

Solutions

  1. Re-run create-turbo in a fresh writable directory
  2. Add an antivirus exclusion for the creation directory, or temporarily pause real-time scanning, then retry
  3. Check write permission on the extracted starter directory and the package.json file itself
  4. Free disk space and confirm the volume allows writes
Defensive patterns

Strategy: try-catch

Validate before calling

import fs from "node:fs";

// confirm the starter directory accepts writes before create-turbo patches it
fs.accessSync(starterDir, fs.constants.W_OK);
fs.accessSync(`${starterDir}/package.json`, fs.constants.W_OK);

Try / catch

try {
  fs.writeJsonSync(pkgPath, content, { spaces: 2 });
} catch (err) {
  const code = (err as NodeJS.ErrnoException).code;
  if (code === "EACCES" || code === "EPERM" || code === "EBUSY") {
    // retry once after a short delay; AV locks on Windows are transient
    await new Promise((r) => setTimeout(r, 500));
    fs.writeJsonSync(pkgPath, content, { spaces: 2 });
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: fs.writeJsonSync on the extracted starter's package.json raises EACCES, EPERM, or EBUSY. The file is read-only, the directory is not writable, an editor or antivirus holds a lock, or the disk is full.

Common situations: Antivirus software on Windows locks recently written files during scaffolding. A read-only checkout or mount. A full disk late in the create process.

Related errors


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

Appendix: source

Thrown at packages/create-turbo/src/transforms/official-starter.ts:84

      if (packageJsonContent.devDependencies?.turbo) {
        // if the user specified a turbo version, use that
        if (opts.turboVersion) {
          packageJsonContent.devDependencies.turbo = opts.turboVersion;
          // use the same version as the create-turbo invocation
        } else {
          // eslint-disable-next-line @typescript-eslint/no-var-requires -- Have to go get package.json
          const version = (require("../../package.json") as { version: string })
            .version;
          packageJsonContent.devDependencies.turbo = `^${version}`;
        }
      }

      try {
        fs.writeJsonSync(rootPackageJsonPath, packageJsonContent, {
          spaces: 2
        });
      } catch (err) {
        throw new TransformError("Unable to write package.json", {
          transform: meta.name,
          fatal: false
        });
      }
    }
  }

  return { result: "success", metaJson, ...meta };
}

View on GitHub (pinned to f9245100cf)