Meituan-Dianping/mpvue · error

Invalid Component definition: ${String(Ctor)}

Error message

Invalid Component definition: ${String(Ctor)}

What it means

During vnode creation, after resolving aliases and `asyncComponent` handling, Vue requires the component option to be a constructor function or an async component factory. If `Ctor` is still not a function, Vue warns with the stringified value and aborts rendering that component.

Source

Thrown at packages/weex-vue-framework/factory.js:3548

  children,
  tag
) {
  if (isUndef(Ctor)) {
    return
  }

  var baseCtor = context.$options._base;

  // plain options object: turn it into a constructor
  if (isObject(Ctor)) {
    Ctor = baseCtor.extend(Ctor);
  }

  // if at this stage it's not a constructor or an async component factory,
  // reject.
  if (typeof Ctor !== 'function') {
    if (process.env.NODE_ENV !== 'production') {
      warn(("Invalid Component definition: " + (String(Ctor))), context);
    }
    return
  }

  // async component
  var asyncFactory;
  if (isUndef(Ctor.cid)) {
    asyncFactory = Ctor;
    Ctor = resolveAsyncComponent(asyncFactory, baseCtor, context);
    if (Ctor === undefined) {
      // return a placeholder node for async component, which is rendered
      // as a comment node but preserves all the raw information for the node.
      // the information will be used for async server-rendering and hydration.
      return createAsyncPlaceholder(
        asyncFactory,
        data,
        context,
        children,

View on GitHub (pinned to 6c5d78ee04)

Solutions

  1. Log `String(Ctor)`/the variable to see what was actually passed (usually `undefined`), then fix the import/registration.
  2. Register the component: `components: { myComp }` locally or `Vue.component('my-comp', MyComp)` globally.
  3. For dynamic components, pass a real options object to `:is` only with `Vue.extend(obj)` or ensure it resolves via `resolveComponent`.
  4. Check circular imports and import timing; use `defineAsyncComponent`/`() => import(...)` for async loading.

Example fix

// before
import Comp from 'my-lib'; // no default export -> undefined
components: { Comp }
// after
import { Comp } from 'my-lib';
components: { Comp }
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof MyComp !== 'function') {
  throw new TypeError(`Invalid component: ${String(MyComp)} — check import/registration`);
}

Type guard

function isValidComponent(Ctor) {
  return typeof Ctor === 'function' || (Ctor && typeof Ctor.render === 'function' && Ctor.cid);
}

Prevention

When it happens

Trigger: Passing a component definition object where a registered/constructor component is expected (e.g. `components: { x: { ... } }` but referencing it with `:is="someObject"` incorrectly), `Vue.component('x', undefined)` then using `<x/>`, a failed default/named import (`import X from 'lib'` where lib has no default, so X is undefined), or passing a string name never registered via `components`.

Common situations: Typo in component registration vs. usage; circular imports yielding `undefined` at module-eval time; mixing Vue 2 object-syntax components into `:is` bindings; dynamic `resolveComponent` on an unregistered tag.

Related errors


AI-assisted analysis of Meituan-Dianping/mpvue@6c5d78ee04 (2026-09-02). Data as JSON: /api/errors/5aba525c26f65b28. Report an issue: GitHub.