{"record":{"id":"36e6f2e70a30c832","repo":"facebook/docusaurus","slug":"copying-local-template-path-source-path-failed","errorCode":null,"errorMessage":"Copying local template path=${source.path} failed!","messagePattern":"Copying local template path=(.+?) failed!","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/create-docusaurus/src/index.ts","lineNumber":517,"sourceCode":"      await fs.rm(path.join(dest, '.git'), {\n        force: true,\n        recursive: true,\n      });\n    }\n  } else if (source.type === 'template') {\n    try {\n      await copyTemplate(source.template, dest, source.language);\n    } catch (err) {\n      throw new Error(\n        logger.interpolate`Copying Docusaurus template name=${source.template.name} failed!`,\n        {cause: err},\n      );\n    }\n  } else {\n    try {\n      await fs.cp(source.path, dest, {recursive: true});\n    } catch (err) {\n      throw new Error(\n        logger.interpolate`Copying local template path=${source.path} failed!`,\n        {cause: err},\n      );\n    }\n  }\n\n  // Update package.json info.\n  try {\n    await updatePkg(path.join(dest, 'package.json'), {\n      name: siteNameToPackageName(siteName),\n      version: '0.0.0',\n      private: true,\n    });\n  } catch (err) {\n    throw new Error('Failed to update package.json.', {cause: err});\n  }\n\n  // We need to rename the gitignore file to .gitignore","sourceCodeStart":499,"sourceCodeEnd":535,"githubUrl":"https://github.com/facebook/docusaurus/blob/3f483e80e326cc646b54b83d564b3f0c4881b9a6/packages/create-docusaurus/src/index.ts#L499-L535","documentation":"Thrown when fs.cp() fails while recursively copying a local template path (source.type === 'local'), i.e. when the user passes a filesystem path to a template directory instead of a built-in template name or git URL. The original fs error is attached as `cause`.","triggerScenarios":"Running `create-docusaurus my-site ./my-template` where my-template is missing, not a directory, or unreadable; a local template that contains a file the current user cannot read; destination filesystem full mid-copy.","commonSituations":"Pointing --template at a relative path that does not resolve from cwd; using a template directory with broken symlinks; copying across filesystems/owners with permission mismatches; the path exists (so the local branch was chosen) but a nested entry is inaccessible.","solutions":["Verify the template path exists and is a directory: ls -la ./my-template.","Use an absolute path to avoid cwd ambiguity: create-docusaurus my-site $(pwd)/my-template.","Inspect err.cause.code (ENOENT/EACCES/ENOSPC) and resolve the underlying filesystem issue.","Fix broken symlinks or unreadable files inside the template tree before retrying."],"exampleFix":"# before\nnpx create-docusaurus my-site ./templat   # typo, path missing\n# after\nnpx create-docusaurus my-site ./template","handlingStrategy":"validation","validationCode":"import path from 'node:path';\nimport fs from 'node:fs/promises';\nasync function assertLocalTemplate(p: string) {\n  const abs = path.resolve(p);\n  const stat = await fs.stat(abs).catch(() => null);\n  if (!stat?.isDirectory()) {\n    throw new Error(`Local template path is not a directory: ${abs}`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await init(name, rootDir, localPath, cliOptions);\n} catch (err) {\n  if (/Copying local template/.test((err as Error).message)) {\n    const code = (err as Error & {cause?: {code?: string}}).cause?.code;\n    // ENOENT -> path typo; EACCES -> permissions\n  }\n  throw err;\n}","preventionTips":["Pass an absolute path for local templates.","Pre-validate the path is a readable directory before invoking init.","Keep templates free of broken symlinks and unreadable files."],"tags":["create-docusaurus","template","filesystem","wrapped-error"],"backgroundTag":null,"analyzedSha":"3f483e80e326cc646b54b83d564b3f0c4881b9a6","analyzedAt":"2026-08-12T13:25:04.382Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}