Resolve the base Vue constructor for tooltip and popover helpers
What does this MR do?
Fixes TypeError: n.show is not a function, thrown by GlTooltip and GlPopover under @vue/compat (Sentry issue GITLABCOM-CLIENTSIDE-2M1VG, 53 users affected in the first 24 hours).
Root cause
- The vendored bootstrap-vue code builds the tooltip helper (
BVTooltip/BVPopover) withnew Ctor({...helperOptions, ...config}), whereCtorisparent.$.appContext.config.globalProperties.constructor. - When the app root is created with
new (Vue.extend(Component))(...), that constructor is theVue.extend()subclass, not the baseVue. Under@vue/compat,new SubVue(options)mergesSubVue.optionsintooptions. - So the helper inherited
Component's props, data and lifecycle hooks. Ashowprop shadowed the helper'sshow()method. Vue warnsMethods property "show" is already defined in Props, then$toolpop.show()throws. BVTransporterreadTeleportfrom the same constructor. The subclass has noTeleport, so the tooltip content was not rendered either.
GitLab hits this in the issuable reference popover, which mounts new (Vue.extend(PopoverComponent))({ propsData: { show: true, ... } }).$mount() on every page with issue or MR links. That explains the Sentry feature_category spread across source_code_management, groups_and_projects and team_planning.
Fix
- Add
getVue3Constructor(instance)to the vendored Vue shim. It walks thesuperchain to the base constructor. - Use it in
createNewChildComponentand inBVTransporter. - Add specs for both. Each fails without the fix under
VUE_VERSION=3.
Verification
VUE_VERSION=3 NODE_ENV=test npx jestandNODE_ENV=test npx jeston the tooltip, popover, transporter and factory specs: 30 passed in each mode.- A Vue 3 Jest repro in
gitlab-org/gitlab(root fromVue.extend,BPopoverwithshow: true) fails onmainwith the Vue warning above and passes with these three files copied intonode_modules/@gitlab/ui/src.
Also seen in GitLab feature specs
The same error fails four feature spec examples in gitlab-org/gitlab as Uncaught TypeError: $toolpop.show is not a function (the unminified form of the Sentry message):
spec/features/work_items/issues/notes_on_issues_spec.rbandee/spec/features/work_items/epics/referencing_epics_spec.rb, both of which render cross-reference notes and hover the reference links.- It fails in both the Vue 2 job (rspec system pg17 19/32) and the Vue 3 job (rspec system pg17 vue3 27/32). In the Vue 2 job the frame is in a
.vue3-commons chunk, so the popover already runs under@vue/compatthere. - Tracked in gitlab-org/gitlab#628901 (section
$toolpop.show is not a function).
Why not fix it in GitLab instead
The consumer uses a valid Vue 2 API, and gitlab-ui claims compat support. Any other consumer that roots an app with Vue.extend() hits the same crash for any prop that matches a helper method name (show, hide, enable, disable), and inherits the root's lifecycle hooks into the helper. Resolving the base constructor fixes all of them. Replacing Vue.extend() roots in GitLab is a separate clean-up.
Screenshots or screen recordings
GDK, issue page under @vue/compat (vue3_migrate_work_items enabled), hovering the #38 reference in a note. Same page, same hover, before and after copying the three changed files into node_modules/@gitlab/ui/src.
Before: no popover, Uncaught TypeError: $toolpop.show is not a function |
|---|
![]() |
| After: popover renders in the Vue 3 realm, no console errors |
|---|
![]() |
Integrations
No API change. GitLab picks the fix up with the next @gitlab/ui bump.
- GitLab: renovate bump
Does this MR meet the acceptance criteria?
- The “What does this MR do?” section explains the reasons for and scope of the change.
- Relevant labels are applied.
- A changeset is added (
patch). - Tests added for the fixed behaviour under both Vue 2 and Vue 3.
References
- Same failure in GitLab feature specs: gitlab-org/gitlab#628901
- Fixes https://gitlab.com/gitlab-org/gitlab/-/work_items/629440 (Sentry mirror of https://new-sentry.gitlab.net/organizations/gitlab/issues/3890449/)
- Triage that pointed at
createNewChildComponentunder compat: https://gitlab.com/gitlab-org/gitlab/-/work_items/629440#note_3844629815 - GitLab consumer that triggers the crash: https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/issuable/popover/index.js

