{"record":{"id":"5d31c40e4358a7a0","repo":"bmad-code-org/BMAD-METHOD","slug":"rehype-markdown-links-could-not-detect-content-d","errorCode":null,"errorMessage":"[rehype-markdown-links] Could not detect content directory for: ${currentFilePath}","messagePattern":"\\[rehype-markdown-links\\] Could not detect content directory for: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"website/src/rehype-markdown-links.js","lineNumber":35,"sourceCode":"\n/**\n * @param {Object} options\n * @param {string} options.base - Site base path (e.g., '/BMAD-METHOD/')\n * @param {string} [options.contentDir] - Absolute path to content root; auto-detected if omitted\n */\nexport default function rehypeMarkdownLinks(options = {}) {\n  const base = options.base || '/';\n  const normalizedBase = base === '/' ? '' : base.replace(/\\/$/, '');\n\n  return (tree, file) => {\n    // The current file's absolute path on disk, set by Astro's markdown pipeline\n    const currentFilePath = file.path;\n    if (!currentFilePath) return;\n\n    // Auto-detect content root: walk up from current file to find src/content/docs\n    const contentDir = options.contentDir || detectContentDir(currentFilePath);\n    if (!contentDir) {\n      throw new Error(`[rehype-markdown-links] Could not detect content directory for: ${currentFilePath}`);\n    }\n\n    visit(tree, 'element', (node) => {\n      if (node.tagName !== 'a' || typeof node.properties?.href !== 'string') {\n        return;\n      }\n\n      const href = node.properties.href;\n\n      // Skip external links (including protocol-relative URLs like //cdn.example.com)\n      if (href.includes('://') || href.startsWith('//') || href.startsWith('mailto:') || href.startsWith('tel:')) {\n        return;\n      }\n\n      // Split href into path vs query+fragment suffix\n      const delimIdx = findFirstDelimiter(href);\n      const linkPath = delimIdx === -1 ? href : href.substring(0, delimIdx);\n      const suffix = delimIdx === -1 ? '' : href.substring(delimIdx);","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/bmad-code-org/BMAD-METHOD/blob/b70486b9bdcb0a404d329e2a763b57964e7f1360/website/src/rehype-markdown-links.js#L17-L53","documentation":"Thrown by the rehype-markdown-links plugin when detectContentDir can't find a content root for the current markdown file. detectContentDir walks the file's path segments looking for 'src/content/docs' (Astro/Starlight convention) or a standalone 'docs' directory; returning null means neither pattern matched, so the plugin cannot compute output URLs.","triggerScenarios":"Running the Astro build on a markdown file whose absolute path contains neither src/content/docs nor a docs segment. Calling the plugin outside its expected content-root layout (file.path is set, which skips the early return, but no recognized root is found above it).","commonSituations":"Restructuring the website content directory away from src/content/docs or docs; running the plugin against files outside the content root; build config changed srcDir; new collection location not covered by detectContentDir's patterns.","solutions":["Pass contentDir explicitly in the plugin options: rehypeMarkdownLinks({ base, contentDir: '/abs/path/to/content' }).","Ensure markdown files live under src/content/docs (Astro) or a docs/ directory so detectContentDir matches.","If the site was restructured, update detectContentDir's pattern or the contentDir option to match the new layout."],"exampleFix":"// before\n//   rehypeMarkdownLinks({ base })   // auto-detect fails on restructured site\n//\n// after\n//   rehypeMarkdownLinks({\n//     base,\n//     contentDir: path.resolve(process.cwd(), 'website/src/content/docs'),\n//   })","handlingStrategy":"validation","validationCode":"const contentDir = options.contentDir || detectContentDir(currentFilePath);\nif (!contentDir) {\n  throw new Error(`Configure rehypeMarkdownLinks({ contentDir: '...' }) for non-standard layouts.`);\n}\n// pass contentDir explicitly in the plugin options\nrehypeMarkdownLinks({ base, contentDir });","typeGuard":"function hasContentDir(filePath) {\n  const seg = filePath.split(path.sep);\n  for (let i = seg.length - 1; i >= 2; i--) {\n    if (seg[i - 2] === 'src' && seg[i - 1] === 'content' && seg[i] === 'docs') return true;\n  }\n  return seg.includes('docs');\n}","tryCatchPattern":"try {\n  astroConfig.rehypePlugins.push([rehypeMarkdownLinks, { base, contentDir }]);\n} catch (e) {\n  if (/Could not detect content directory/.test(e.message)) {\n    // fall back to explicit contentDir resolved from process.cwd()\n  } else { throw e; }\n}","preventionTips":["Always pass contentDir explicitly when the site deviates from src/content/docs.","Keep markdown under the recognized content root so auto-detection works.","If you restructure content, update the plugin options in the same change."],"tags":["website","rehype","astro","build","content-dir"],"backgroundTag":null,"analyzedSha":"b70486b9bdcb0a404d329e2a763b57964e7f1360","analyzedAt":"2026-08-13T01:21:12.247Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}