facebook / docusaurus

Easy to maintain open source documentation websites.
https://docusaurus.io
MIT License
56.85k stars 8.56k forks source link

Docusaurus build fails with "No Docusaurus route context found" for manually created sidebar with many items #10718

Open DonaldKellett opened 1 day ago

DonaldKellett commented 1 day ago

Have you read the Contributing Guidelines on issues?

Prerequisites

Description

This is a duplicate of #10709 which was closed due to lacking a reproducible example. So here's a reproducible example: https://github.com/DonaldKellett/docusaurus-10709-repro

Building our production Technical KB written in Docusaurus with npm run build recently failed consistently with the error message below.

[cause]: Error: Unexpected: no Docusaurus route context found

The problem is reproducible in that the error appears 100% of the time when we try to add just 1 more item to our manually created sidebar (maybe our sidebar is too large?) regardless of what the item is or where it is placed within the sidebar, but our Docusaurus site contains sensitive and confidential information so we can't share the source code here. Nevertheless, we'll try to include as much relevant information as possible to help reproduce the issue without divulging too many details.

Reproducible demo

https://github.com/DonaldKellett/docusaurus-10709-repro

Steps to reproduce

Without divulging too many details, we're using Docusaurus v3.6.1 with the @docusaurus/faster plugin enabled though we found that the issue persists regardless of whether the experimental plugin is enabled or disabled.

Our package.json and package-lock.json files are as attached. In particular, the version of p-map used as seen in package-lock.json is 4.0.0 which is important as we will see later:

The issue is consistently triggered when we try to add 1 more item anywhere within our manually created sidebar in sidebars.js. Here's an overview of what it looks like:

/**
 * Creating a sidebar enables you to:
 - create an ordered group of docs
 - render a sidebar for each doc of that group
 - provide next/previous navigation

 The sidebars can be generated from the filesystem, or explicitly defined here.

 Create as many sidebars as you want.
 */

// @ts-check

/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
  // By default, Docusaurus generates a sidebar from the docs folder structure
  // tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],

  // But you can create a sidebar manually
  docs: [
    {
      type: "category",
      label: "GitLab",
      link: {
        type: "generated-index",
        title: "GitLab",
        description: "Articles related to GitLab",
      },
      items: [
        {
          type: "category",
          label: "Administrator Guide",
          link: {
            type: "generated-index",
            title: "Administrator Guide",
            description: "Administrator Guide for GitLab Helm Chart",
          },
          items: [
            "gitlab/install-gitlab-with-helm",
            "gitlab/enable-git-over-ssh-for-gitlab",
            "gitlab/enable-ad-login-for-gitlab",
            "gitlab/gitlab-properly-signed-tls",
            "gitlab/enable-gitlab-managed-terraform-backend",
            "gitlab/provide-custom-ca-gitlab-ci-jobs",
            "gitlab/cron-backup-gitlab-ee-16.x",
            "gitlab/gitlab-runner-https-certificate-error",
          ],
        },
        ...
      ]
    },
    ...
  ]
};

module.exports = sidebars;

For reference, here's what our docusaurus.config.js looks like (portions omitted due to containing sensitive information):

// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion

const lightCodeTheme = require("prism-react-renderer").themes.github;
const darkCodeTheme = require("prism-react-renderer").themes.dracula;

/** @type {import('@docusaurus/types').Config} */
const config = {
  future: {
    experimental_faster: true,
  },
  title: "Technical KB",
  tagline: "Internal technical knowledge base for Enfinity",
  favicon: "img/favicon.ico",

  // Set the production url of your site here
  url: "https://enfinity-solutions.pages.internal.enfinity.com.hk/",
  // Set the /<baseUrl>/ pathname under which your site is served
  // For GitHub pages deployment, it is often '/<projectName>/'
  baseUrl: "/internal/technical-kb/",

  // GitHub pages deployment config.
  // If you aren't using GitHub pages, you don't need these.
  organizationName: "facebook", // Usually your GitHub org/user name.
  projectName: "docusaurus", // Usually your repo name.

  onBrokenLinks: "throw",
  onBrokenMarkdownLinks: "warn",

  // Even if you don't use internalization, you can use this field to set useful
  // metadata like html lang. For example, if your site is Chinese, you may want
  // to replace "en" with "zh-Hans".
  i18n: {
    defaultLocale: "en",
    locales: ["en"],
  },

  presets: [
    [
      "classic",
      /** @type {import('@docusaurus/preset-classic').Options} */
      ({
        docs: {
          sidebarPath: require.resolve("./sidebars.js"),
          editUrl:
            "https://gitlab.internal.enfinity.com.hk/enfinity-solutions/internal/technical-kb/-/tree/main/",
        },
        blog: false,
        theme: {
          customCss: require.resolve("./src/css/custom.css"),
        },
      }),
    ],
  ],

  themeConfig:
    /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
    ({
      // Replace with your project's social card
      image: "img/docusaurus-social-card.jpg",
      navbar: {
        title: "Technical KB",
        logo: {
          alt: "My Site Logo",
          src: "img/logo.svg",
        },
        items: [
          { to: "/docs/category/gitlab", label: "GitLab", position: "left" },
          { to: "/docs/category/cloud", label: "Cloud", position: "left" },
          ...,
          {
            href: "https://gitlab.internal.enfinity.com.hk/enfinity-solutions/internal/technical-kb",
            label: "GitLab",
            position: "right",
          },
        ],
      },
      footer: {
        style: "dark",
        links: [
          {
            title: "Docs",
            items: [
              {
                label: "GitLab",
                to: "/docs/category/gitlab",
              },
              {
                label: "Cloud",
                to: "/docs/category/cloud",
              },
              ...
            ],
          },
          {
            title: "More",
            items: [
              {
                label: "GitLab",
                href: "https://gitlab.internal.enfinity.com.hk/enfinity-solutions/internal/technical-kb",
              },
            ],
          },
        ],
        copyright: `Copyright © ${new Date().getFullYear()} Enfinity Solutions Limited. Built with Docusaurus.`,
      },
      prism: {
        theme: lightCodeTheme,
        darkTheme: darkCodeTheme,
      },
    }),
};

module.exports = config;

Expected behavior

Building the site with npm run build finishes without issues. The site loads and displays correctly with npm run serve.

Actual behavior

Docusaurus static site generation failed for 306 paths:

> website@0.0.0 build
> docusaurus build
[INFO] [en] Creating an optimized production build...
[ERROR] Error: Unable to build website for locale en.
    at tryToBuildLocale (/builds/enfinity-solutions/internal/technical-kb/node_modules/@docusaurus/core/lib/commands/build/build.js:78:15)
    at async /builds/enfinity-solutions/internal/technical-kb/node_modules/@docusaurus/core/lib/commands/build/build.js:34:9
    at async mapAsyncSequential (/builds/enfinity-solutions/internal/technical-kb/node_modules/@docusaurus/utils/lib/jsUtils.js:21:24)
    at async Command.build (/builds/enfinity-solutions/internal/technical-kb/node_modules/@docusaurus/core/lib/commands/build/build.js:33:5) {
  [cause]: Error: Docusaurus static site generation failed for 306 paths:
...

The detailed error for each failure is "Error: Unexpected: no Docusaurus route context found" which can be traced down to p-map/index.js:57:22 and is identical for each failure.

Error: Can't render static file for pathname "/internal/technical-kb/docs/aiml/install-pyenv"
            at generateStaticFile (/builds/enfinity-solutions/internal/technical-kb/node_modules/@docusaurus/core/lib/ssg/ssg.js:167:15)
            at processTicksAndRejections (node:internal/process/task_queues:105:5)
            at runNextTicks (node:internal/process/task_queues:69:3)
            at process.processImmediate (node:internal/timers:459:9)
            at async /builds/enfinity-solutions/internal/technical-kb/node_modules/p-map/index.js:57:22 {
          [cause]: Error: Unexpected: no Docusaurus route context found
              at mergeContexts (server.bundle.js:10977:19)
              at server.bundle.js:10995:16
              at Object.Ic [as useMemo] (server.bundle.js:3227:240)
              at __webpack_modules__.72408.exports.useMemo (server.bundle.js:4808:208)
              at RouteContextProvider (server.bundle.js:10994:69)
              at Uc (server.bundle.js:3234:44)
              at Xc (server.bundle.js:3236:253)
              at Z (server.bundle.js:3242:89)
              at Vc (server.bundle.js:3234:473)
              at Xc (server.bundle.js:3236:210)
        },

The offending line in version 4.0.0 of p-map is: https://github.com/sindresorhus/p-map/blob/a4b4dec459544d98880bc53a580e53691aff9fa9/index.js#L57

result[index] = await mapper(element, index);

Screenshots containing the error messages in our failing GitLab CI builds are attached below.

2024-11-22 12_15_40-Window 2024-11-22 12_15_11-Window

Your environment

Self-service

DonaldKellett commented 1 day ago

Here's the commit that triggers the bug causing the build to fail: https://github.com/DonaldKellett/docusaurus-10709-repro/commit/2c4431b741c1b30008f45af64fa6057e173ce3ef As can be seen from the commit, adding just a single item to the sidebar anywhere triggers this cryptic build error.

The failing job and build logs in CI: https://github.com/DonaldKellett/docusaurus-10709-repro/actions/runs/11983861175/job/33413927236

DonaldKellett commented 4 hours ago

Just discovered that the build error disappears when duplicate sub-category names are renamed to become unique, e.g. these 2:

  1. "Kubernetes > Storage": https://github.com/DonaldKellett/docusaurus-10709-repro/blob/main/sidebars.js#L233-L248
  2. "OpenShift > Storage": https://github.com/DonaldKellett/docusaurus-10709-repro/blob/main/sidebars.js#L488-L502

Nevertheless, I insist this is a bug in Docusaurus since the build process should catch duplicated sub-category names in the sidebar if it is not a supported use-case and exit with a human-readable error message instead of exhibiting unspecified behavior and randomly failing builds with a cryptic error message when a certain number of sidebar items is reached.