OrchardCMS/OrchardCore · error · Error

Transition-group inside component is not supported. Please…

Error message

Transition-group inside component is not supported. Please alter tag value or remove transition-group. Current tag value: 

What it means

vuedraggable's mounted() checks whether the rendered root element tag matches the configured tag. When they differ (a 'non-functional component mode') AND a transition-group transition mode is active, the drag/transition integration cannot work, so it throws this Error. It protects users from a silently non-functional animated drag list.

Solutions

  1. Set tag explicitly to the element that will actually render, e.g. tag="tbody" for table rows or tag="div"
  2. If you don't need animations, remove the transition-group/component-data/transition-mode configuration
  3. Wrap animation differently: put transition-group outside and use draggable without transition-mode
  4. Pin vuedraggable 2.24.x usage patterns per docs when combining tag + transition

Example fix

// before
<draggable :list="items" tag="section" :component-data="{ is: 'transition-group' }">

// after
<draggable :list="items" tag="ul" :component-data="{ tag: 'ul', name: 'flip-list', type: 'transition' }">
<!-- rendered root tag must equal configured tag -->
Defensive patterns

Strategy: validation

Validate before calling

const rootTag = component.$el?.nodeName?.toLowerCase(); const configured = getTag().toLowerCase(); if (rootTag !== configured && usesTransitionMode) { console.warn('tag mismatch with transition-group; fix tag prop'); }

Type guard

null

Try / catch

try { mountDraggable(); } catch (e) { if (e.message.startsWith('Transition-group inside component')) { console.error('Fix the tag prop or remove transition-mode', e); } else { throw e; } }

Prevention

When it happens

Trigger: Using <draggable tag="div"> (or default tag) whose rendered root doesn't match getTag() while passing transition-mode/transition-group props, e.g. setting the transition props but rendering the component as a functional/component wrapper, or customizing tag so the root node name differs (e.g. tag='transition-group' style misconfig).

Common situations: Copy-pasting Vue 2 transition-group examples into wrappers that change the root tag; using <draggable :component-data> with mismatched tag and is='transition-group'; upgrading Vue where root node normalization changed.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/fca9b198999342db. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.Resources/wwwroot/Vendor/vue-draggable-2.24.3/vuedraggable.common.js:2146

    if (this.list !== null && this.value !== null) {
      helper["b" /* console */].error("Value and list props are mutually exclusive! Please set one or another.");
    }

    if (this.element !== "div") {
      helper["b" /* console */].warn("Element props is deprecated please use tag props instead. See https://github.com/SortableJS/Vue.Draggable/blob/master/documentation/migrate.md#element-props");
    }

    if (this.options !== undefined) {
      helper["b" /* console */].warn("Options props is deprecated, add sortable options directly as vue.draggable item, or use v-bind. See https://github.com/SortableJS/Vue.Draggable/blob/master/documentation/migrate.md#options-props");
    }
  },
  mounted: function mounted() {
    var _this3 = this;

    this.noneFunctionalComponentMode = this.getTag().toLowerCase() !== this.$el.nodeName.toLowerCase() && !this.getIsFunctional();

    if (this.noneFunctionalComponentMode && this.transitionMode) {
      throw new Error("Transition-group inside component is not supported. Please alter tag value or remove transition-group. Current tag value: ".concat(this.getTag()));
    }

    var optionsAdded = {};
    eventsListened.forEach(function (elt) {
      optionsAdded["on" + elt] = delegateAndEmit.call(_this3, elt);
    });
    eventsToEmit.forEach(function (elt) {
      optionsAdded["on" + elt] = emit.bind(_this3, elt);
    });
    var attributes = Object.keys(this.$attrs).reduce(function (res, key) {
      res[Object(helper["a" /* camelize */])(key)] = _this3.$attrs[key];
      return res;
    }, {});
    var options = Object.assign({}, this.options, attributes, optionsAdded, {
      onMove: function onMove(evt, originalEvent) {
        return _this3.onDragMove(evt, originalEvent);
      }
    });

View on GitHub (pinned to 4306c0717f)