vercel/turborepo · error · TransformError
Unable to read package.json
Error message
Unable to read package.json
What it means
Thrown by create-turbo's official-starter transform after it downloads and extracts a starter example: it reads the extracted root package.json with fs.readJsonSync to adjust the project name and turbo version. If that file is missing, unreadable, or not valid JSON, this non-fatal TransformError is thrown.
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.jsonView on GitHub (pinned to 9f94a7d215)
Solutions
- Delete the partial output directory and simply re-run create-turbo (transient download/extraction failures are the most common cause)
- If using --example with a custom path, verify that path directly contains a valid package.json (test with `node -e "JSON.parse(require('fs').readFileSync('<path>/package.json','utf8'))"`)
- Check disk space and directory permissions, then retry
- Fall back to a known-good official example name (e.g. `--example basic`) to rule out the custom source
Example fix
# before npx create-turbo@latest --example ./my-broken-example my-app # after npx create-turbo@latest --example basic my-app
Defensive patterns
Strategy: validation
Validate before calling
import fs from 'node:fs';
function isValidExampleDir(dir: string): boolean {
const pkg = `${dir}/package.json`;
if (!fs.existsSync(pkg)) return false;
try {
JSON.parse(fs.readFileSync(pkg, 'utf8'));
return true;
} catch {
return false;
}
}
// run before: createTurbo({ example: myDir }) requires isValidExampleDir(myDir) Try / catch
try {
await createApp({ example });
} catch (err) {
if (err instanceof TransformError && err.transform === meta.name) {
// message 'Unable to read package.json': safest recovery is cleanup + one retry
await fs.rm(targetDir, { recursive: true, force: true });
return createApp({ example }); // one bounded retry, then surface
}
throw err;
} Prevention
- Validate custom --example directories contain a parseable root package.json before scaffolding
- Pin the create-turbo version in CI (`create-turbo@x.y.z`) to avoid surprise starter-layout changes
- Treat a first failure on flaky networks as transient: clean the partial output and retry once before debugging
When it happens
Trigger: fs.readJsonSync(rootPackageJsonPath) throwing inside the transform: the starter extraction was incomplete (interrupted download/disk-full), a custom --example path has no root package.json, a permissions error, or the file contains malformed/truncated JSON.
Common situations: Flaky network cutting off example download mid-extract; passing --example a local directory or GitHub repo whose package.json sits in a subfolder; corporate proxies mangling tarballs; truncated files after a full disk.
Related errors
- Unable to write package.json
- Unable to write .gitignore
- Unable to update README.md
- Generator config directory already exists at ${configDirecto
- isErrorLike(reason) ? reason.message : String(reason)
AI-assisted analysis of vercel/turborepo@9f94a7d215 (2026-08-16).
Data as JSON: /api/errors/a4301aabc7b7e475.
Report an issue: GitHub.