Meituan-Dianping/mpvue · error

<${el.tag} v-model="${value}">: v-model is not supported on

Error message

<${el.tag} v-model="${value}">: v-model is not supported on this element type. If you are working with contenteditable, it's recommended to wrap a library dedicated for that purpose inside a custom component.

What it means

v-model was applied to an element the compiler can neither treat as a native form control nor as a component: it is a reserved native tag that is not a supported input element. The compiler warns in dev mode instead of generating model code.

Source

Thrown at src/platforms/web/compiler/directives/model.js:60

  if (el.component) {
    genComponentModel(el, value, modifiers)
    // component v-model doesn't need extra runtime
    return false
  } else if (tag === 'select') {
    genSelect(el, value, modifiers)
  } else if (tag === 'input' && type === 'checkbox') {
    genCheckboxModel(el, value, modifiers)
  } else if (tag === 'input' && type === 'radio') {
    genRadioModel(el, value, modifiers)
  } else if (tag === 'input' || tag === 'textarea') {
    genDefaultModel(el, value, modifiers)
  } else if (!config.isReservedTag(tag)) {
    genComponentModel(el, value, modifiers)
    // component v-model doesn't need extra runtime
    return false
  } else if (process.env.NODE_ENV !== 'production') {
    warn(
      `<${el.tag} v-model="${value}">: ` +
      `v-model is not supported on this element type. ` +
      'If you are working with contenteditable, it\'s recommended to ' +
      'wrap a library dedicated for that purpose inside a custom component.'
    )
  }

  // ensure runtime directive metadata
  return true
}

function genCheckboxModel (
  el: ASTElement,
  value: string,
  modifiers: ?ASTModifiers
) {
  const number = modifiers && modifiers.number
  const valueBinding = getBindingAttr(el, 'value') || 'null'

View on GitHub (pinned to 6c5d78ee04)

Solutions

  1. Remove v-model or replace with :value + @input / manual event handling.
  2. For contenteditable, use a dedicated library wrapped in a custom component, then v-model the component (component v-model is supported).
  3. If you meant a form control, use input/textarea/select instead.

Example fix

// before
<div v-model="message" contenteditable></div>
// after
<content-editor v-model="message"></content-editor>
Defensive patterns

Strategy: validation

Validate before calling

const V_MODEL_NATIVE_OK = new Set(['input', 'textarea', 'select'])
function assertVModelTarget (template) {
  const tags = Array.from(template.matchAll(/<(\w+)[^>]*\sv-model/g)).map(m => m[1])
  for (const t of tags) {
    if (!V_MODEL_NATIVE_OK.has(t)) {
      throw new Error('v-model on <' + t + '> is unsupported; use a component or form control')
    }
  }
}
assertVModelTarget('<div v-model="x">')

Prevention

When it happens

Trigger: Compiling e.g. `<div v-model="x">`, `<p v-model="y">`, `<span v-model="z">` — genDefaultModel not applicable, genComponentModel skipped because config.isReservedTag(tag) is true.

Common situations: Trying to two-way bind an arbitrary element's text; v-model on contenteditable divs; stray v-model left on a wrapper element after refactoring.

Related errors


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