itwanger/toBeBetterJavaer · error · Error

Route not found in sidebar.ts: ${target.route}

Error message

Route not found in sidebar.ts: ${target.route}

What it means

Thrown by syncTarget() in scripts/sync-sidebar.js when findRouteArray() cannot locate the target route as a key in sidebar.ts. The lookup is a literal regex: a quoted string equal to the route (normalized with leading/trailing slashes) followed by optional whitespace, a colon, and an opening bracket. Any deviation in the sidebar source — different quoting, template literal, or extra whitespace before the colon beyond what \s* allows — makes the route invisible.

Source

Thrown at scripts/sync-sidebar.js:187

function syncTarget(source, target) {
  const dir = path.resolve(ROOT_DIR, target.dir);
  const report = {
    route: target.route,
    dir: path.relative(ROOT_DIR, dir),
    added: [],
    removed: [],
    warnings: [],
  };

  if (!fs.existsSync(dir)) {
    throw new Error(`Markdown directory not found: ${target.dir}`);
  }

  const files = collectMarkdownSlugs(dir);
  const blockRange = findRouteArray(source, target.route);
  if (!blockRange) {
    throw new Error(`Route not found in sidebar.ts: ${target.route}`);
  }

  let block = source.slice(blockRange.start, blockRange.end + 1);
  const refs = collectRefs(block);
  const listedSlugs = new Set(refs.map((ref) => ref.slug));
  const fileSlugs = new Set(files.map((file) => file.slug));

  const staleSlugs = [...listedSlugs].filter((slug) => !fileSlugs.has(slug));
  if (staleSlugs.length > 0) {
    const removal = removeStaleStringEntries(block, staleSlugs);
    block = removal.block;
    report.removed = removal.removed;

    for (const slug of staleSlugs) {
      if (!removal.removed.includes(slug)) {
        report.warnings.push(`Stale ref "${slug}" is not a plain string entry; remove it manually if needed.`);
      }
    }

View on GitHub (pinned to 6617f5fd0b)

Solutions

  1. Open sidebar.ts, find the target section, and make sure it has a literal key exactly like `"/sidebar/itwanger/ai/": [` — quotes, slashes, colon, bracket
  2. Match your --route to the existing key exactly (normalizeRoute adds surrounding slashes automatically)
  3. If the section is new, first add an empty array entry for the route in sidebar.ts, then run sync to populate it

Example fix

// sidebar.ts — before: no such route key
export const sidebar = {
  "/sidebar/itwanger/": { /* ... */ },
};

// after: add the route as a literal array so sync can populate it
export const sidebar = {
  "/sidebar/itwanger/": { /* ... */ },
  "/sidebar/itwanger/ai/": [],
};
Defensive patterns

Strategy: type-guard

Validate before calling

// Confirm the route key exists as a literal array before running sync
const src = fs.readFileSync(sidebarPath, "utf8");
const re = new RegExp(["([\\\"'])"].join("") + route.replace(/\//g, "\\/") + "\\1\\s*:\\s*\\[");
if (!re.test(src)) console.error(`Add \"${route}\": [] to sidebar.ts first`);

Type guard

const routeExistsInSidebar = (src, route) => new RegExp(`(["'])${route.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\1\\s*:\\s*\\[`).test(src);

Try / catch

catch (err) { if (err.message.startsWith("Route not found in sidebar.ts:")) { console.error("Create the route entry as a literal quoted key with an array value, then rerun"); process.exit(2); } throw err; }

Prevention

When it happens

Trigger: Route key in sidebar.ts spelled differently (`/sidebar/itwanger/ai` without trailing slash, or a deeper/shallower path) than the --route value; the key exists but its value is not an array literal (`route: someVariable`); quoting mismatch (backtick template literal vs quote); route genuinely not yet added to sidebar.ts.

Common situations: Adding a new content section and running sync before creating the sidebar entry; refactoring sidebar.ts to computed keys or spread objects; trailing-slash inconsistency between the CLI arg and the file.

Related errors


AI-assisted analysis of itwanger/toBeBetterJavaer@6617f5fd0b (2026-08-14). Data as JSON: /api/errors/0d941f5aa5a8f06d. Report an issue: GitHub.