vercel/turborepo · warning · TransformError
Unable to update README.md
Error message
Unable to update README.md
What it means
Thrown by create-turbo's update-commands-in-readme transform, which rewrites package-manager command references inside the starter's README.md (e.g. swapping `pnpm run`/`yarn` commands for the manager you selected) using fs.readFile then fs.writeFile. Any read or write failure inside that try block raises this non-fatal TransformError.
Source
Thrown at packages/create-turbo/src/transforms/update-commands-in-readme.ts:53
if (!prompts.packageManager) {
return { result: "not-applicable", ...meta };
}
const readmeFilePath = path.join(prompts.root, "README.md");
if (!fs.existsSync(readmeFilePath)) {
return { result: "not-applicable", ...meta };
}
try {
const data = await fs.readFile(readmeFilePath, "utf8");
const updatedData = replacePackageManagerReferences(
prompts.packageManager.name,
data
);
await fs.writeFile(readmeFilePath, updatedData, "utf8");
} catch (err) {
throw new TransformError("Unable to update README.md", {
transform: meta.name,
fatal: false
});
}
return { result: "success", ...meta };
}
/**
* Within backtick-delimited code regions, replaces package manager references:
* - "<pm> run" → "<selected> run"
* - bare "<pm>" (not followed by "run") → "<selected>"
*/
export function replacePackageManagerReferences(
targetPm: PackageManager,
text: string
): string {
return text.replace(CODE_REGION_REGEX, (codeBlock) => {View on GitHub (pinned to 9f94a7d215)
Solutions
- Ensure the project directory and README.md are writable, close any program holding the file, and re-run create-turbo
- Free disk space and retry
- Treat it as cosmetic if the rest of the scaffold succeeded: the README only needs its `<pm> run` commands swapped to your package manager — do a find/replace manually
Example fix
# before: pnpm-managed starter README kept 'pnpm run dev' # after (manual fix): replace with your manager's commands npm run dev # if npm was selected
Defensive patterns
Strategy: try-catch
Validate before calling
import fs from 'node:fs';
function readmeRewritable(p: string): boolean {
try {
fs.accessSync(p, fs.constants.R_OK | fs.constants.W_OK);
return true;
} catch {
return false;
}
} Try / catch
try {
await runTransforms(args);
} catch (err) {
if (err instanceof TransformError && /README/.test(err.message)) {
// cosmetic step: log and continue, then fix the README by hand
console.warn('README update skipped — replace <pm> run commands manually');
} else throw err;
} Prevention
- Close editors holding README.md before scaffolding
- Treat this transform as optional — never gate CI on it
- If it recurs on Windows, exclude the project folder from real-time AV scanning
When it happens
Trigger: The transform first guards with existsSync (a missing README yields 'not-applicable'), so the throw comes from the IO itself: EACCES/EROFS on README.md, the file being locked by another process, or ENOSPC. A read/write race (README deleted between existsSync and readFile) also lands here.
Common situations: README.md locked by an open editor or antivirus on Windows; scaffolding into a read-only or non-writable directory; disk full at the tail end of scaffolding.
Related errors
- Unable to write .gitignore
- Unable to read package.json
- Unable to write package.json
- 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/b7803481374c0a45.
Report an issue: GitHub.