{"record":{"id":"b967f6d1889a6603","repo":"itwanger/toBeBetterJavaer","slug":"markdown-directory-not-found-target-dir","errorCode":null,"errorMessage":"Markdown directory not found: ${target.dir}","messagePattern":"Markdown directory not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/sync-sidebar.js","lineNumber":181,"sourceCode":"    }\n  } catch (error) {\n    console.error(`sync-sidebar: ${error.message}`);\n    process.exitCode = 1;\n  }\n}\n\nfunction syncTarget(source, target) {\n  const dir = path.resolve(ROOT_DIR, target.dir);\n  const report = {\n    route: target.route,\n    dir: path.relative(ROOT_DIR, dir),\n    added: [],\n    removed: [],\n    warnings: [],\n  };\n\n  if (!fs.existsSync(dir)) {\n    throw new Error(`Markdown directory not found: ${target.dir}`);\n  }\n\n  const files = collectMarkdownSlugs(dir);\n  const blockRange = findRouteArray(source, target.route);\n  if (!blockRange) {\n    throw new Error(`Route not found in sidebar.ts: ${target.route}`);\n  }\n\n  let block = source.slice(blockRange.start, blockRange.end + 1);\n  const refs = collectRefs(block);\n  const listedSlugs = new Set(refs.map((ref) => ref.slug));\n  const fileSlugs = new Set(files.map((file) => file.slug));\n\n  const staleSlugs = [...listedSlugs].filter((slug) => !fileSlugs.has(slug));\n  if (staleSlugs.length > 0) {\n    const removal = removeStaleStringEntries(block, staleSlugs);\n    block = removal.block;\n    report.removed = removal.removed;","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/itwanger/toBeBetterJavaer/blob/6617f5fd0b0597735bdc028f2fcd036817877327/scripts/sync-sidebar.js#L163-L199","documentation":"Thrown by syncTarget() in scripts/sync-sidebar.js when the Markdown directory for a target (from --dir or the built-in DEFAULT_TARGETS) does not exist after resolving against the repo root. It fires after the sidebar file check but before any sidebar.ts parsing, and aborts the whole run (not just that target).","triggerScenarios":"`--dir` with a typo'd or moved directory; a fork where docs/src/sidebar/itwanger/ai does not exist so even the default target fails; passing a file instead of a directory (collectMarkdownSlugs expects a directory to walk).","commonSituations":"Content reorganization moving sidebar content dirs; wrong repo-relative base; new clones of repos without the sidebar content subtree; case mismatch in directory names.","solutions":["Verify the directory: `ls docs/src/sidebar/itwanger/ai` and fix the --dir value","Give --dir a repo-root-relative path (it is path.resolve(ROOT_DIR, dir))","If the default target is wrong for your fork, always pass explicit --route/--dir for an existing section"],"exampleFix":"# before\nnode scripts/sync-sidebar.js --route=sidebar/itwanger/ai --dir=docs/src/sidebar/itwangr/ai\n\n# after\nnode scripts/sync-sidebar.js --route=sidebar/itwanger/ai --dir=docs/src/sidebar/itwanger/ai","handlingStrategy":"validation","validationCode":"const dir = path.resolve(REPO_ROOT, dirArg);\nif (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) { console.error(`Directory missing: ${dirArg} (resolves to ${dir})`); process.exit(2); }","typeGuard":"const isMarkdownDir = (p) => { const d = path.resolve(REPO_ROOT, p); return fs.existsSync(d) && fs.statSync(d).isDirectory(); };","tryCatchPattern":"catch (err) { if (err.message.startsWith(\"Markdown directory not found:\")) { console.error(\"Fix --dir; must be a repo-root-relative directory\"); process.exit(2); } throw err; }","preventionTips":["Tab-complete the --dir value","The default target assumes docs/src/sidebar/itwanger/ai exists — in forks without it, always pass explicit --route/--dir","Run from the repo root to keep relative paths intuitive"],"tags":["filesystem","cli","configuration"],"backgroundTag":null,"analyzedSha":"6617f5fd0b0597735bdc028f2fcd036817877327","analyzedAt":"2026-08-14T14:50:55.107Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}