{"record":{"id":"af48c71b661780bf","repo":"vercel/next.js","slug":"docs-folder-not-found-in-cloned-repository","errorCode":null,"errorMessage":"docs folder not found in cloned repository","messagePattern":"docs folder not found in cloned repository","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/next-codemod/lib/agents-md.ts","lineNumber":228,"sourceCode":"          '.',\n        ],\n        { cwd: tempDir }\n      )\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error)\n      if (message.includes('not found') || message.includes('did not match')) {\n        throw new Error(\n          `Could not find documentation for Next.js ${tag}. This version may not exist on GitHub yet.`\n        )\n      }\n      throw error\n    }\n\n    await execa('git', ['sparse-checkout', 'set', 'docs'], { cwd: tempDir })\n\n    const sourceDocsDir = path.join(tempDir, 'docs')\n    if (!fs.existsSync(sourceDocsDir)) {\n      throw new Error('docs folder not found in cloned repository')\n    }\n\n    if (fs.existsSync(destDir)) {\n      fs.rmSync(destDir, { recursive: true })\n    }\n    fs.mkdirSync(destDir, { recursive: true })\n    fs.cpSync(sourceDocsDir, destDir, { recursive: true })\n  } finally {\n    if (fs.existsSync(tempDir)) {\n      fs.rmSync(tempDir, { recursive: true })\n    }\n  }\n}\n\nexport function collectDocFiles(dir: string): { relativePath: string }[] {\n  return (fs.readdirSync(dir, { recursive: true }) as string[])\n    .filter(\n      (f) =>","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/packages/next-codemod/lib/agents-md.ts#L210-L246","documentation":"After `agents-md` successfully clones the repo at the version tag, it runs `git sparse-checkout set docs` and then asserts the `docs/` folder exists in the working tree. If it doesn't, this error is thrown. It indicates the clone succeeded but the sparse checkout produced no `docs` directory — e.g. the tag predates the `docs/` folder, the sparse-checkout filter mis-fired, or the repo layout at that tag differs from current.","triggerScenarios":"Running `agents-md` against an old tag whose repository structure didn't include a top-level `docs/` folder; a git/fs hiccup where sparse-checkout left an empty worktree; disk/permission errors during checkout.","commonSituations":"Very old Next.js versions where docs lived elsewhere; transient filesystem/git errors in CI; sparse-checkout version mismatch on the git binary available.","solutions":["Use a newer tag that definitely has a top-level `docs/` folder, or pass a version override with a known-good tag.","Prefer the bundled docs path (Next 16.2+) which reads from `node_modules/next/dist/docs` and avoids cloning.","Verify git supports sparse-checkout (`git sparse-checkout list`) and rerun.","Manually clone `--branch <tag>` and confirm `docs/` exists to identify tag/layout issues."],"exampleFix":"# verify the tag has a docs folder\ngit clone --depth 1 --branch v15.1.6 https://github.com/vercel/next.js.git /tmp/njs && ls /tmp/njs/docs\n# if missing, pick a newer tag or use bundled docs\nnpx @next/codemod agents-md --version 16.2.0","handlingStrategy":"validation","validationCode":"// Pre-check the tag has a docs folder by listing the sparse tree.\nimport { execSync } from 'node:child_process'\nconst out = execSync(`git ls-remote --tags https://github.com/vercel/next.js.git v${ver}`).toString()\nif (!out) throw new Error('Tag missing; pick a newer version with docs/')","typeGuard":null,"tryCatchPattern":"try {\n  await cloneDocsFolder(tag, dest)\n} catch (e) {\n  if (/docs folder not found/.test(e.message)) {\n    console.error('Use a newer tag or bundled docs.')\n  }\n  throw e\n}","preventionTips":["Prefer bundled docs (Next 16.2+) to avoid clone layout issues.","Pin a known-good version tag.","Confirm local git supports sparse-checkout."],"tags":["next-codemod","agents-md","git","sparse-checkout","documentation","filesystem"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}