facebook/docusaurus · error · Error

Failed to update package.json.

Error message

Failed to update package.json.

What it means

Thrown when updatePkg() fails to read or write the package.json that create-docusaurus expects to find (and patch with name/version/private) in the freshly copied destination. updatePkg parses, merges, and re-serializes JSON, so any parse error or write failure bubbles up here with the original error as `cause`.

Source

Thrown at packages/create-docusaurus/src/index.ts:532

    try {
      await fs.cp(source.path, dest, {recursive: true});
    } catch (err) {
      throw new Error(
        logger.interpolate`Copying local template path=${source.path} failed!`,
        {cause: err},
      );
    }
  }

  // Update package.json info.
  try {
    await updatePkg(path.join(dest, 'package.json'), {
      name: siteNameToPackageName(siteName),
      version: '0.0.0',
      private: true,
    });
  } catch (err) {
    throw new Error('Failed to update package.json.', {cause: err});
  }

  // We need to rename the gitignore file to .gitignore
  if (
    !(await pathExists(path.join(dest, '.gitignore'))) &&
    (await pathExists(path.join(dest, 'gitignore')))
  ) {
    await fs.rename(
      path.join(dest, 'gitignore'),
      path.join(dest, '.gitignore'),
    );
  }
  if (await pathExists(path.join(dest, 'gitignore'))) {
    await fs.rm(path.join(dest, 'gitignore'));
  }

  // Display the most elegant way to cd.
  const cdpath = path.relative('.', dest);

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Open <dest>/package.json in a JSON validator and fix syntax errors, then re-run init in a clean directory.
  2. Confirm the template has package.json at its root (not in a subdirectory).
  3. Check err.cause.code: ENOENT means the template lacks package.json, EACCES/EROFS means a permissions issue.
  4. Re-run create-docusaurus into a fresh destination after fixing the template.

Example fix

// before (template package.json with a trailing comma)
{
  "name": "x",
  "version": "1.0.0",
}
// after
{
  "name": "x",
  "version": "1.0.0"
}
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs/promises';
async function assertValidPackageJson(filePath: string) {
  const raw = await fs.readFile(filePath, 'utf8');
  try { JSON.parse(raw); } catch {
    throw new Error(`package.json at ${filePath} is not valid JSON`);
  }
}

Try / catch

try {
  await init(...);
} catch (err) {
  if (/Failed to update package\.json/.test((err as Error).message)) {
    // open <dest>/package.json, validate JSON, fix, retry in a clean dest
  }
  throw err;
}

Prevention

When it happens

Trigger: A custom or local template whose package.json is malformed JSON; a git-cloned template that has no package.json at the repo root; a read-only destination that blocks the write-back; an EISDIR/ENOENT because the path is a directory or missing.

Common situations: Using a community git template whose package.json has trailing commas or comments; a template that stores package.json in a subfolder instead of the root; running on a read-only mount; a previous copy step partially failed leaving a corrupt package.json.

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/db37ed80fb82d5fc. Report an issue: GitHub.