Vue-router error: missing required param by visiting route without any required params

Hi,
Got a issue with my page routing, coming from a specific page in my app and using a router-link to navigate to other pages results in the following error:
Uncaught (in promise) Error: Missing required param “guildId”
and breaks the navigation. It only happens when i attempt to navigate from my “/stats/:guildId” to other pages. Navigating from “/” to “/commands” or “/help” works fine.
Here’s my router code:

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue')
  },
  {
    path: '/help',
    props: true,
    name: 'Help',
    redirect: '/help/firststeps',
    component: () => import('../views/help/Help.vue'),
    children: [
      {
        path: ':article',
        name: 'Help',
        props: true,
        component: () => import('../views/help/HelpArticleView.vue')
      }
    ]
  },
  {
    path: '/commands',
    name: 'Commands',
    redirect: '/commands/acceptsub',
    component: () => import('../views/commands/Commands.vue'),
    children: [
      {
        path: ':command',
        name: 'Command',
        props: true,
        component: () => import('../views/commands/CommandView.vue')
      }
    ]
  },
  {
    path: '/stats',
    name: 'stats-search',
    component: () => import('../views/stats/GuildSearch.vue')
  },
  {
    path: '/stats/:guildId',
    name: 'stats-view',
    props: true,
    component: () => import('../views/stats/StatsView.vue'),
    children: [
      {
        path: 'overview',
        name: 'overview',
        props: true,
        component: () => import('../views/stats/Overview.vue')
      },
      {
        path: 'history',
        name: 'history',
        props: true,
        component: () => import('../views/stats/PickupHistory.vue')
      },
      {
        path: 'player',
        name: 'player-search',
        props: true,
        component: () => import('../views/stats/PlayerSearch.vue')
      },
    ]
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
});

We don’t really know which route you are trying to achieve but according to Routes imbriquées | Vue Router

when you call your children (overview for exemple) you are actually calling /stats/:guildId/overview so you need a param

When i access routes nested in stats-view i of course need to pass the guildId as param. Navigating in the child components of “stats/:guildId” works fine. But attempting to navigate to for example “/” for my Home component results in the error. The issue is that there are no required params in the routes i try to access from my stats-view child components. Adding some fake guildId to my “/” router-link works. Also navigating from any other route than “/stats/:guildId” and its nested routes works fine.

Committed my code changes to my repo, should be easier to spot errors now:
https://github.com/slice3984/pickup-bot/tree/vue-frontend/www/src
I also created some temporary fix to not break the navigation here:
https://github.com/slice3984/pickup-bot/blob/vue-frontend/www/src/router/index.ts#L81
I hope someone can help me to fix this issue since i still got no idea what’s causing it.

I am getting exactly the same issue, using Vue 3

I can navigate to all routes, until I have navigated to one with a parameter. When I navigate back, I get the same error

Uncaught (in promise) Error: Missing required param "clientId"
    at Object.stringify (vue-router.esm-bundler.js:994)

I will keep digging

The workaround I have gone for so far is to make the parameter optional on the ‘from’ route

path: ‘/brands/:clientId’ → path: ‘/brands/:clientId?’


    {
        path: '/brands/:clientId?',
        props: true,
        component: () => import('#/views/Brand.vue'),
        children: [
            {
                name: 'Brand',
                path: '',
                meta: {
                    diplayName: 'All',
                },
                component: () =>
                    import('#/components/Campaign/list.vue'),
            },
            {
                path: 'manage',
                name: 'Manage Campaign',
                meta: {
                    diplayName: 'Manage Campaign',
                },
                component: () => import('#/views/Campaigns/manage.vue'),
            },
        ],
    }

That didn’t fix it

I have logged a bug and a repo to reproduce

1 Like

Updating to vertion 4.0.6 fixed this issue for me

I’m experiencing this very same issue. I’m using @quasar/app v3.1.0, which utilizes vue-router 4.0.11. Even though this issue was supposed to have been fixed in 4.0.6, it’s still happening for me. Help?

const routes = [
  {
    path: "/",
    component: () => import("layouts/MainLayout.vue"),
    children: [
      {
        path: "",
        name: "home",
        component: () => import("pages/Dashboard.vue"),
      },
    ],
  },
  {
    path: "/personnel",
    component: () => import("layouts/MainLayout.vue"),
    children: [
      {
        path: "list",
        name: "personnel-list",
        component: () => import("pages/Personnel/PersonnelList.vue"),
      },
      {
        path: ":employeeId",
        component: () => import("pages/Personnel/PersonnelDetail.vue"),
        props: true,
        children: [
          {
            path: "identity",
            name: "personnel-identity",
            component: () =>
              import("components/Personnel/PersonnelIdentity.vue"),
            props: true,
          },
          {
            path: "docs",
            name: "personnel-docs",
            component: () => import("components/Personnel/PersonnelDocs.vue"),
            props: true,
          },
          {
            path: "roles",
            name: "personnel-roles",
            component: () => import("components/Personnel/PersonnelRoles.vue"),
            props: true,
          },
          {
            path: "training",
            name: "personnel-training",
            component: () =>
              import("components/Personnel/PersonnelTraining.vue"),
            props: true,
          },
          {
            path: "reviews",
            name: "personnel-reviews",
            component: () =>
              import("components/Personnel/PersonnelReviews.vue"),
            props: true,
          },
        ],
      },
    ],
  },
  {
    path: "/:catchAll(.*)*",
    component: () => import("pages/Error404.vue"),
  },
];

As long as I’m navigating back and forth within the /personnel/:employeeId/ child routes, things work great. It’s only when I navigate from one of those routes to one without an :employeeId, such as home. Then I get this set of errors:

[Vue warn]: Unhandled error during execution of watcher getter 
  at <QRouteTab label="Identity" to= 
Object { name: "personnel-identity" }
 > 
  at <QTabs dense="" class="text-grey" active-color="primary"  ... > 
  at <QPage padding="" > 
  at <PersonnelDetail employeeId="3" onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< 
Proxy { <target>: {…}, <handler>: {…} }
 > > 
  at <RouterView> 
  at <QPageContainer> 
  at <QLayout view="hHh lpR fFf" class="bg-grey-1" > 
  at <MyLayout onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< 
Proxy { <target>: {…}, <handler>: {…} }
 > > 
  at <RouterView> 
  at <App> runtime-core.esm-bundler.js:6873

[Vue Router warn]: uncaught error during route navigation: vue-router.esm-bundler.js:72

Error: Missing required param "employeeId"
    stringify vue-router.esm-bundler.js:1005
    resolve vue-router.esm-bundler.js:1423
    resolve vue-router.esm-bundler.js:2877
    linkRoute use-router-link.js:84
    run reactivity.esm-bundler.js:160
    get value reactivity.esm-bundler.js:1087
    setup QRouteTab.js:30
    callWithErrorHandling runtime-core.esm-bundler.js:6990
    getter runtime-core.esm-bundler.js:7335
    run reactivity.esm-bundler.js:160
    job runtime-core.esm-bundler.js:7371
    flushPreFlushCbs runtime-core.esm-bundler.js:7163
    flushJobs runtime-core.esm-bundler.js:7204
    promise callback*queueFlush runtime-core.esm-bundler.js:7120
    queueCb runtime-core.esm-bundler.js:7142
    queuePostFlushCb runtime-core.esm-bundler.js:7148
    queueEffectWithSuspense runtime-core.esm-bundler.js:1450
    scheduler runtime-core.esm-bundler.js:7404
    triggerEffects reactivity.esm-bundler.js:358
    triggerRefValue reactivity.esm-bundler.js:948
    effect reactivity.esm-bundler.js:1076
    triggerEffects reactivity.esm-bundler.js:358
    triggerRefValue reactivity.esm-bundler.js:948
    effect reactivity.esm-bundler.js:1076
    triggerEffects reactivity.esm-bundler.js:358
    triggerRefValue reactivity.esm-bundler.js:948
    set value reactivity.esm-bundler.js:987
    finalizeNavigation vue-router.esm-bundler.js:3156
    pushWithRedirect vue-router.esm-bundler.js:3029
    promise callback*pushWithRedirect vue-router.esm-bundler.js:3000
    push vue-router.esm-bundler.js:2931
    navigateToLink use-router-link.js:196
    onClick QItem.js:101
    callWithErrorHandling runtime-core.esm-bundler.js:6990
    callWithAsyncErrorHandling runtime-core.esm-bundler.js:6999
    invoker runtime-dom.esm-bundler.js:347
vue-router.esm-bundler.js:3264
    triggerError vue-router.esm-bundler.js:3264
    handleScroll vue-router.esm-bundler.js:3303
    (Async: promise callback)
    handleScroll vue-router.esm-bundler.js:3303
    finalizeNavigation vue-router.esm-bundler.js:3157
    pushWithRedirect vue-router.esm-bundler.js:3029
    (Async: promise callback)
    pushWithRedirect vue-router.esm-bundler.js:3000
    push vue-router.esm-bundler.js:2931
    navigateToLink use-router-link.js:196
    onClick QItem.js:101
    callWithErrorHandling runtime-core.esm-bundler.js:6990
    callWithAsyncErrorHandling runtime-core.esm-bundler.js:6999
    invoker runtime-dom.esm-bundler.js:347

Uncaught (in promise) Error: Missing required param "employeeId"
    stringify vue-router.esm-bundler.js:1005
    resolve vue-router.esm-bundler.js:1423
    resolve vue-router.esm-bundler.js:2877
    linkRoute use-router-link.js:84
    run reactivity.esm-bundler.js:160
    get value reactivity.esm-bundler.js:1087
    setup QRouteTab.js:30
    callWithErrorHandling runtime-core.esm-bundler.js:6990
    getter runtime-core.esm-bundler.js:7335
    run reactivity.esm-bundler.js:160
    job runtime-core.esm-bundler.js:7371
    flushPreFlushCbs runtime-core.esm-bundler.js:7163
    flushJobs runtime-core.esm-bundler.js:7204
    promise callback*queueFlush runtime-core.esm-bundler.js:7120
    queueCb runtime-core.esm-bundler.js:7142
    queuePostFlushCb runtime-core.esm-bundler.js:7148
    queueEffectWithSuspense runtime-core.esm-bundler.js:1450
    scheduler runtime-core.esm-bundler.js:7404
    triggerEffects reactivity.esm-bundler.js:358
    triggerRefValue reactivity.esm-bundler.js:948
    effect reactivity.esm-bundler.js:1076
    triggerEffects reactivity.esm-bundler.js:358
    triggerRefValue reactivity.esm-bundler.js:948
    effect reactivity.esm-bundler.js:1076
    triggerEffects reactivity.esm-bundler.js:358
    triggerRefValue reactivity.esm-bundler.js:948
    set value reactivity.esm-bundler.js:987
    finalizeNavigation vue-router.esm-bundler.js:3156
    pushWithRedirect vue-router.esm-bundler.js:3029
    promise callback*pushWithRedirect vue-router.esm-bundler.js:3000
    push vue-router.esm-bundler.js:2931
    navigateToLink use-router-link.js:196
    onClick QItem.js:101
    callWithErrorHandling runtime-core.esm-bundler.js:6990
    callWithAsyncErrorHandling runtime-core.esm-bundler.js:6999
    invoker runtime-dom.esm-bundler.js:347

I’m using Quasar, if that makes any difference, although the fact that the error is based on a missing param points to vue-router as being the core issue.

@ryan-hyer same experience here. I’m using quasar too but i get the same issue whether I use router-link or the quasar components so you’re probably right that it’s a vue-router issue.

Did you manage to resolve this or find a workaround?

@zagreusinoz, yes, it’s working fine for me now, and I believe the error was mine. I had to declare props: ["employeeId"] in every single one of the affected child components, even if I don’t actually use that prop within that particular component. After I did that, I haven’t run into that error again.

For example:

<script>
import PersonnelTabsDropdown from "./PersonnelTabsDropdown.vue";

export default {
  name: "PersonnelReviews",
  components: { PersonnelTabsDropdown },
  props: ["employeeId"],
  setup(props) {},
};
</script>

I don’t really understand why that worked (I’m still fairly new to Vue, let alone vue-router), but it did.