Skip to content

Uncaught Invariant Violation: Item not found in navigation #5120

@bambier

Description

@bambier

Steps to reproduce

RouteManager.jsx

import { ThemeContext } from "@emotion/react";
import CircularProgress from "@mui/material/CircularProgress";
import { UserContext } from "context/UserContext";
import Offline from "pages/public/Offline";
import { lazy, Suspense, useContext } from "react";
import { Route, Routes } from "react-router-dom";
import { ToastContainer } from "react-toastify";


const Private = lazy(() => import("./Private"));
const Public = lazy(() => import("./Public"));


export default function RouteManager() {
	const userCntx = useContext(UserContext);
	const themeContext = useContext(ThemeContext);

	return (
		<>
			<Suspense fallback={<CircularProgress sx={{ mx: "auto", my: "50%" }} />}>
				<Routes>
					{
						userCntx.isAuthenticated ? <Route path="/dashboard/*" element={<Private />} /> : null
					}
					<Route path="/offline/" element={<Offline />} />
					<Route index path="/*" element={<Public />} />

				</Routes >
				<ToastContainer
					autoClose={5000}
					rtl={true}
					pauseOnFocusLoss
					draggable
					pauseOnHover
					theme={themeContext.isDarkMode ? "dark" : "light"}
				/>
			</Suspense>
		</>
	);
}

Private.jsx

import { Alert, Box, CircularProgress, useTheme } from '@mui/material';
import { PageContainer } from '@toolpad/core';
import { DashboardLayout } from '@toolpad/core/DashboardLayout';
import { ReactRouterAppProvider } from "@toolpad/core/react-router";
import urls from 'api/urls';
import logo from "assets/images/logo.png";
import useGetObj from "hooks/useGetObj";
import { lazy, useEffect, useState } from "react";
import { Route, Routes } from 'react-router-dom';
import get_pages from "utils/get_pages";

const Dashboard = lazy(() => import("pages/private/dashboard/MainDashboard"));
const Profile = lazy(() => import("pages/private/profile/Profile"));
const AddArticle = lazy(() => import("pages/private/Articles/AddArticle"));
const ArticleList = lazy(() => import("pages/private/Articles/ArticleList"));
const Users = lazy(() => import("pages/private/users/Users"));


const branding = {
	homeUrl: "/",
	logo: <img src={logo} alt="Logo" />,
	title: "Website"
};

export default function Private() {
	const theme = useTheme();
	const [navigation, setNavigation] = useState([]);
	const [user, isLoaded, error] = useGetObj({ url: `${urls.account}profile/` });

	useEffect(() => {

		if (isLoaded && !error && user) {
			const pages = get_pages(user);
			setNavigation(pages);
		}
	}, [user, isLoaded, error]);


	if (!isLoaded) {
		return <Box sx={{ mt: 20, textAlign: 'center' }}><CircularProgress /></Box>;
	} else if ((isLoaded && user === null) || error) {
		return (
			<Box sx={{ mt: 20, textAlign: 'center', p: 5 }}>
				<Alert severity='error'>
  Error
				</Alert>
			</Box>
		);
	}
	else if (isLoaded && !user.is_active) {
		return (
			<Box sx={{ mt: 20, textAlign: 'center', p: 5 }}>
				<CircularProgress />
			</Box>
		);
	} else {
		return (
			<ReactRouterAppProvider theme={theme} branding={branding} navigation={navigation} session={user} >
				<DashboardLayout>
					<PageContainer>
						<Routes>
							<Route path="/" exact index element={<Dashboard />} />
							<Route path='profile/' element={<Profile />} />

							{
								user.is_superuser ?
									<>
										<Route path='article/' element={<AddArticle />} />
										<Route path='article/add/' element={<AddArticle />} />
										<Route path='article/list/' element={<ArticleList />} />
										<Route path='users/' element={<Users />} />
									</> : null
							}

						</Routes>
					</PageContainer>
				</DashboardLayout>
			</ReactRouterAppProvider>
		);
	}
}

getPages.js

import CreateRoundedIcon from '@mui/icons-material/CreateRounded';
import DashboardIcon from '@mui/icons-material/Dashboard';
import NewspaperRoundedIcon from '@mui/icons-material/NewspaperRounded';
import PersonRoundedIcon from '@mui/icons-material/PersonRounded';
import SegmentRoundedIcon from '@mui/icons-material/SegmentRounded';


const Base_NAVIGATION = [
    {
        kind: 'header',
        title: 'User Dashboard',
    },
    {
        segment: 'dashboard',
        pattern: 'dashboard(/)?',
        title: 'Dashboard',
        icon: <DashboardIcon />,
    },
    {
        segment: 'dashboard/profile',
        pattern: 'dashboard/profile(/)?',
        title: 'Profile',
        icon: <PersonRoundedIcon />,
    },
];

export default function get_pages(user) {
    const pages = Base_NAVIGATION;
    if (user.is_superuser) {
        pages.push(
            {
                kind: 'header',
                title: 'Auther Dashboard',
            },
            {
                segment: 'dashboard/article',
                pattern: 'dashboard/article(/)?',
                title: 'Articles',
                icon: <NewspaperRoundedIcon />,
                children: [
                    {
                        segment: 'add',
                        pattern: 'dashboard/article/add(/)?', // Add full pattern
                        title: 'Add',
                        icon: <CreateRoundedIcon />
                    },
                    {
                        segment: 'list',
                        pattern: 'dashboard/article/list(/)?', // Add full pattern
                        title: 'List',
                        icon: <SegmentRoundedIcon />
                    },
                ]
            },

        );

        return pages;
    }




    return pages;
}

Note: Just use dummy component for Route elements. It doesn't matter because they are empty screens like

function Untitled() {
    return (
        <div>Untitled</div>
    )
}

export default Untitled;

Current behavior

Page doesn't shows up and says

Item not found in navigation: Add
invariant@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7730:15
getItemPath@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7028:41
./node_modules/@toolpad/core/esm/shared/navigation.js/hasSelectedNavigationChildren/<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7044:33
hasSelectedNavigationChildren@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7037:26
./node_modules/@toolpad/core/esm/DashboardLayout/DashboardSidebarSubNavigation.js/DashboardSidebarSubNavigation/initialExpandedItemIds</<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5732:194
./node_modules/@toolpad/core/esm/DashboardLayout/DashboardSidebarSubNavigation.js/DashboardSidebarSubNavigation/initialExpandedItemIds<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5730:7
mountMemo@http://localhost:3000/static/js/bundle.js:46922:21
useMemo@http://localhost:3000/static/js/bundle.js:55131:16
./node_modules/react/cjs/react.development.js/exports.useMemo@http://localhost:3000/static/js/bundle.js:70415:32
DashboardSidebarSubNavigation@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5727:69
react_stack_bottom_frame@http://localhost:3000/static/js/bundle.js:56014:18
renderWithHooks@http://localhost:3000/static/js/bundle.js:46224:38
updateFunctionComponent@http://localhost:3000/static/js/bundle.js:47917:17
beginWork@http://localhost:3000/static/js/bundle.js:48503:16
runWithFiberInDEV@http://localhost:3000/static/js/bundle.js:43995:125
performUnitOfWork@http://localhost:3000/static/js/bundle.js:50576:93
workLoopSync@http://localhost:3000/static/js/bundle.js:50469:55
renderRootSync@http://localhost:3000/static/js/bundle.js:50453:7
performWorkOnRoot@http://localhost:3000/static/js/bundle.js:50217:42
performSyncWorkOnRoot@http://localhost:3000/static/js/bundle.js:51181:22
flushSyncWorkAcrossRoots_impl@http://localhost:3000/static/js/bundle.js:51100:306
flushSpawnedWork@http://localhost:3000/static/js/bundle.js:50878:36
commitRoot@http://localhost:3000/static/js/bundle.js:50722:7
commitRootWhenReady@http://localhost:3000/static/js/bundle.js:50287:15

Also console log is

Uncaught Invariant Violation: Item not found in navigation: Add
    invariant http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7730
    getItemPath http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7028
    node_modules toolpad/core/esm/shared/navigation.js/hasSelectedNavigationChildren/<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7044
    hasSelectedNavigationChildren http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7037
    node_modules toolpad/core/esm/DashboardLayout/DashboardSidebarSubNavigation.js/DashboardSidebarSubNavigation/initialExpandedItemIds</<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5732
    node_modules toolpad/core/esm/DashboardLayout/DashboardSidebarSubNavigation.js/DashboardSidebarSubNavigation/initialExpandedItemIds<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5730
    mountMemo http://localhost:3000/static/js/bundle.js:46922
    useMemo http://localhost:3000/static/js/bundle.js:55131
    useMemo http://localhost:3000/static/js/bundle.js:70415
    DashboardSidebarSubNavigation http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5727
    react_stack_bottom_frame http://localhost:3000/static/js/bundle.js:56014
    renderWithHooks http://localhost:3000/static/js/bundle.js:46224
    updateFunctionComponent http://localhost:3000/static/js/bundle.js:47917
    beginWork http://localhost:3000/static/js/bundle.js:48503
    runWithFiberInDEV http://localhost:3000/static/js/bundle.js:43995
    performUnitOfWork http://localhost:3000/static/js/bundle.js:50576
    workLoopSync http://localhost:3000/static/js/bundle.js:50469
    renderRootSync http://localhost:3000/static/js/bundle.js:50453
    performWorkOnRoot http://localhost:3000/static/js/bundle.js:50217
    performSyncWorkOnRoot http://localhost:3000/static/js/bundle.js:51181
    flushSyncWorkAcrossRoots_impl http://localhost:3000/static/js/bundle.js:51100
    flushSpawnedWork http://localhost:3000/static/js/bundle.js:50878
    commitRoot http://localhost:3000/static/js/bundle.js:50722
    commitRootWhenReady http://localhost:3000/static/js/bundle.js:50287
    setTimeout handler*performWorkOnRoot http://localhost:3000/static/js/bundle.js:50264
    performWorkOnRootViaSchedulerTask http://localhost:3000/static/js/bundle.js:51173
    performWorkUntilDeadline http://localhost:3000/static/js/bundle.js:70529
    js http://localhost:3000/static/js/bundle.js:70648
    js http://localhost:3000/static/js/bundle.js:70755
    factory http://localhost:3000/static/js/bundle.js:77884
    __webpack_require__ http://localhost:3000/static/js/bundle.js:77239
    fn http://localhost:3000/static/js/bundle.js:77500
    hotRequire http://localhost:3000/static/js/bundle.js:77867
    js http://localhost:3000/static/js/bundle.js:70770
    factory http://localhost:3000/static/js/bundle.js:77884
    __webpack_require__ http://localhost:3000/static/js/bundle.js:77239
    fn http://localhost:3000/static/js/bundle.js:77500
    hotRequire http://localhost:3000/static/js/bundle.js:77867
    js http://localhost:3000/static/js/bundle.js:53775
    js http://localhost:3000/static/js/bundle.js:56776
    factory http://localhost:3000/static/js/bundle.js:77884
    __webpack_require__ http://localhost:3000/static/js/bundle.js:77239
    fn http://localhost:3000/static/js/bundle.js:77500
    hotRequire http://localhost:3000/static/js/bundle.js:77867
    js http://localhost:3000/static/js/bundle.js:57000
    factory http://localhost:3000/static/js/bundle.js:77884
    __webpack_require__ http://localhost:3000/static/js/bundle.js:77239
    fn http://localhost:3000/static/js/bundle.js:77500
    hotRequire http://localhost:3000/static/js/bundle.js:77867
    js http://localhost:3000/static/js/bundle.js:76668
    factory http://localhost:3000/static/js/bundle.js:77884
    __webpack_require__ http://localhost:3000/static/js/bundle.js:77239
    <anonymous> http://localhost:3000/static/js/bundle.js:78488
    <anonymous> http://localhost:3000/static/js/bundle.js:78490
[vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7730:15](http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js)
An error occurred in the <DashboardSidebarSubNavigation> component.

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://react.dev/link/error-boundaries to learn more about error boundaries.

Expected behavior

Show pages under /dashboard/ path instead of root or anything else without any error.

Context

I have 2 routes.

  1. Public
  2. Private

Public URLs are under root (/) and private URL which needs authentication and are under dashboard (/dashboard).

get_pages is responsible for getting dashboard pages according user accesses and permissions.
RouteManager is responsible for checking for users authentication and let them to access private pages

I tried many approaches to put side navigation's in dashboard under /dashboard/ in this scenario but either they went under root url (when I change url/pattern in get_pages) or just not shows up when I put location prop to Routes in Private.jsx.

Your environment

Firefox

npx @mui/envinfo


  System:
    OS: Linux 6.14 Ubuntu 24.04.3 LTS 24.04.3 LTS (Noble Numbat)
  Binaries:
    Node: 22.13.0 - ~/.nvm/versions/node/v22.13.0/bin/node
    npm: 10.9.2 - ~/.nvm/versions/node/v22.13.0/bin/npm
    pnpm: Not Found
  Browsers:
    Chrome: Not Found
  npmPackages:
    @emotion/react: ^11.14.0 => 11.14.0 
    @emotion/styled: ^11.14.1 => 11.14.1 
    @mui/core-downloads-tracker:  7.3.1 
    @mui/icons-material: 7.3.1 => 7.3.1 
    @mui/material: 7.3.1 => 7.3.1 
    @mui/private-theming:  7.3.1 
    @mui/styled-engine:  7.3.1 
    @mui/styled-engine-sc: 7.3.1 => 7.3.1 
    @mui/system:  7.3.1 
    @mui/types:  7.4.5 
    @mui/utils:  7.3.1 
    @mui/x-data-grid:  8.10.1 
    @mui/x-date-pickers: ^8.10.0 => 8.10.0 
    @mui/x-internals:  8.10.0 
    @mui/x-virtualizer:  0.1.2 
    @toolpad/core: ^0.16.0 => 0.16.0 
    @toolpad/utils:  0.16.0 
    react: ^19.1.1 => 19.1.1 
    react-dom: ^19.1.1 => 19.1.1 
    styled-components: ^6.1.19 => 6.1.19 
    typescript: ^5.9.2 => 5.9.2 

Search keywords: navigation, react

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions