Meituan-Dianping/mpvue · warning

Avoid deleting properties on a Vue instance or its root…

Error message

Avoid deleting properties on a Vue instance or its root $data - just set it to null.

What it means

Warning from Vue.delete / vm.$delete (del in observer/index.js) when the target is a Vue instance or the root $data object. Deleting keys from these breaks the reactive dependency graph, so Vue warns and instead recommends setting the property to null.

Solutions

  1. Replace the delete with an assignment to null (or undefined semantics via null)
  2. Nest such keys one level down in a data sub-object so Vue.delete works reactively
  3. Declare the key permanently in data and toggle its value instead of removing it
  4. If the item belongs to a list, remove it from the array with splice or $delete on the array index

Example fix

// before
this.$delete(this.$data, 'draft')
// after
data() { return { draft: null } }
methods: { clearDraft() { this.draft = null } }
Defensive patterns

Strategy: validation

Validate before calling

function isSafeDeleteTarget(target) {
  return target != null && typeof target === 'object' && !target._isVue && !(target.__ob__ && target.__ob__.vmCount)
}

Type guard

function isRootReactive(t) { return t != null && (t._isVue === true || (t.__ob__ && t.__ob__.vmCount > 0)) }

Prevention

When it happens

Trigger: Vue.delete(vm, 'someKey'); Vue.delete(this.$data, 'someKey'); this.$delete(this.$data, key) in cleanup logic; using the delete operator on root data keys via a wrapper.

Common situations: Cleanup after removing form fields or list items stored at root; state-reset utilities that prune keys; code translated from plain-object state management where delete was routine.

Related errors


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

Appendix: source

Thrown at src/core/observer/index.js:268

  if (!target.__keyPath) {
    def(target, '__keyPath', {}, false)
  }
  target.__keyPath[key] = true
  ob.dep.notify()
  return val
}

/**
 * Delete a property and trigger change if necessary.
 */
export function del (target: Array<any> | Object, key: any) {
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.splice(key, 1)
    return
  }
  const ob = (target: any).__ob__
  if (target._isVue || (ob && ob.vmCount)) {
    process.env.NODE_ENV !== 'production' && warn(
      'Avoid deleting properties on a Vue instance or its root $data ' +
      '- just set it to null.'
    )
    return
  }
  if (!hasOwn(target, key)) {
    return
  }
  delete target[key]
  if (!ob) {
    return
  }
  if (!target.__keyPath) {
    def(target, '__keyPath', {}, false)
  }
  // Vue.del 删除对象属性,渲染时候把这个属性设置为 undefined
  target.__keyPath[key] = 'del'
  ob.dep.notify()

View on GitHub (pinned to 6c5d78ee04)