vercel/turborepo · error · TransformError

Unable to read package.json

Error message

Unable to read package.json

What it means

The official-starter transform in create-turbo reads the root package.json of the downloaded starter with fs.readJsonSync. It throws this TransformError when the file cannot be read or parsed as JSON. This means the starter's package.json is missing at read time, unreadable, or contains malformed JSON.

Solutions

  1. If you used a custom --example, open its package.json in a JSON validator and fix any syntax errors
  2. Re-run create-turbo with the default example to confirm the tool works, then retry your custom example
  3. Check that the extracted starter directory is readable and was not modified by antivirus or proxy software
  4. If an official example fails, report the broken example to the Turborepo repository

Example fix

// before: invalid JSON in the example's package.json
{ "name": "my-app", "version": "1.0.0", }
// after: valid JSON
{
  "name": "my-app",
  "version": "1.0.0"
}
Defensive patterns

Strategy: validation

Validate before calling

import fs from "node:fs";

// validate a custom example's package.json before passing it to create-turbo
function hasValidRootPackageJson(exampleDir: string): boolean {
  try {
    const raw = fs.readFileSync(`${exampleDir}/package.json`, "utf8");
    const parsed = JSON.parse(raw);
    return typeof parsed === "object" && parsed !== null;
  } catch {
    return false;
  }
}

Type guard

function isValidJsonFile(raw: string): boolean {
  try {
    JSON.parse(raw);
    return true;
  } catch {
    return false;
  }
}

Try / catch

try {
  const pkg = fs.readJsonSync(pkgPath);
} catch (err) {
  const reason = (err as NodeJS.ErrnoException).code === "ENOENT"
    ? "package.json is missing"
    : "package.json is not valid JSON";
  throw new Error(`${reason}: ${pkgPath}`);
}

Prevention

When it happens

Trigger: create-turbo downloads an example whose root package.json is not valid JSON, or the file cannot be opened due to permissions or a corrupted download. fs.readJsonSync throws inside the try block and the catch converts it to this TransformError.

Common situations: Using --example with a custom repository that has a syntax error in package.json, such as a trailing comma or a smart quote. A proxy or antivirus altering the extracted file. An example repository whose layout changed so the copied root lacks a valid package.json.

Related errors


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

Appendix: source

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

  let metaJson: MetaJson | undefined;

  // 1. remove meta file (used for generating the examples page on turborepo.dev)
  try {
    metaJson = fs.readJsonSync(rootMetaJsonPath) as MetaJson;
    fs.rmSync(rootMetaJsonPath, { force: true });
  } catch (_err) {
    // do nothing
  }

  if (hasPackageJson) {
    let packageJsonContent: PackageJson | undefined;
    try {
      packageJsonContent = fs.readJsonSync(rootPackageJsonPath) as
        | PackageJson
        | undefined;
    } catch {
      throw new TransformError("Unable to read package.json", {
        transform: meta.name,
        fatal: false
      });
    }

    // if using the basic example, set the name to the project name (legacy behavior)
    if (packageJsonContent) {
      if (defaultExample) {
        packageJsonContent.name = prompts.projectName;
      }

      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

View on GitHub (pinned to f9245100cf)