vercel/turborepo · error · TransformError
Unable to write package.json
Error message
Unable to write package.json
What it means
Thrown by create-turbo's official-starter transform when it cannot write the modified starter package.json back to disk. The transform mutates the starter's package.json (sets the project name for the basic example, pins the bundled turbo version) and persists it with fs.writeJsonSync; any failure of that write raises this non-fatal TransformError.
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 9f94a7d215)
Solutions
- Ensure the target directory is writable (`chmod u+w <dir>` / run under $HOME) and re-run create-turbo
- Close editors and pause cloud-sync/antivirus for the scaffold directory, then retry
- Check free disk space (`df -h .`) and retry
- If the scaffold otherwise completed, fix it manually: open the created package.json and set `name` and `devDependencies.turbo` yourself
Example fix
# before npx create-turbo@latest my-app # fails while OneDrive locks package.json # after # pause sync (or scaffold outside the synced folder), then: npx create-turbo@latest my-app
Defensive patterns
Strategy: try-catch
Validate before calling
import fs from 'node:fs';
function canWriteFile(p: string): boolean {
try {
fs.accessSync(fs.dirname ?? fsConstants(p), fs.constants.W_OK);
return true;
} catch {
return false;
}
}
// simpler: fs.accessSync(projectRoot, fs.constants.W_OK) before invoking create-turbo Try / catch
try {
await createApp({ root });
} catch (err) {
if (err instanceof TransformError && err.fatal === false && /package\.json/.test(err.message)) {
// recover manually: apply the two mutations yourself (project name + turbo version)
const pkg = JSON.parse(fs.readFileSync(`${root}/package.json`, 'utf8'));
pkg.devDependencies ??= {};
pkg.devDependencies.turbo = `^${installedTurboVersion}`;
fs.writeFileSync(`${root}/package.json`, JSON.stringify(pkg, null, 2));
} else throw err;
} Prevention
- Scaffold outside cloud-synced folders, or pause sync during scaffolding
- Add antivirus exclusions for your projects directory on Windows
- Confirm the target directory is writable before invoking create-turbo
When it happens
Trigger: fs.writeJsonSync(rootPackageJsonPath, packageJsonContent, { spaces: 2 }) throwing: EACCES/EROFS on the project root, ENOSPC, or EPERM because the file is locked by antivirus, an editor, or a sync client (typical on Windows).
Common situations: Scaffolding into an unwritable or read-only directory; OneDrive/Dropbox locking package.json as it syncs; endpoint protection scanning files the moment they are written; CI workspace mounted read-only.
Related errors
- Unable to write .gitignore
- Unable to read package.json
- Unable to update README.md
- unexpected error reading "package.json" at ${workspaceRoot}
- Generator config directory already exists at ${configDirecto
AI-assisted analysis of vercel/turborepo@9f94a7d215 (2026-08-16).
Data as JSON: /api/errors/248968f1778b9a19.
Report an issue: GitHub.