Meituan-Dianping/mpvue · warning
Failed watching path: "${expOrFn}" Watcher only accepts simp
Error message
Failed watching path: "${expOrFn}" Watcher only accepts simple dot-delimited paths. For full control, use a function instead. What it means
Warning from the Watcher constructor when the expression string passed as expOrFn cannot be parsed into a valid dot-delimited path (parsePath returns undefined). The watcher is created with a noop getter so it never fires, meaning the watch silently does nothing after this warning.
Source
Thrown at src/core/observer/watcher.js:77
this.cb = cb
this.id = ++uid // uid for batching
this.active = true
this.dirty = this.lazy // for lazy watchers
this.deps = []
this.newDeps = []
this.depIds = new Set()
this.newDepIds = new Set()
this.expression = process.env.NODE_ENV !== 'production'
? expOrFn.toString()
: ''
// parse expression for getter
if (typeof expOrFn === 'function') {
this.getter = expOrFn
} else {
this.getter = parsePath(expOrFn)
if (!this.getter) {
this.getter = function () {}
process.env.NODE_ENV !== 'production' && warn(
`Failed watching path: "${expOrFn}" ` +
'Watcher only accepts simple dot-delimited paths. ' +
'For full control, use a function instead.',
vm
)
}
}
this.value = this.lazy
? undefined
: this.get()
}
/**
* Evaluate the getter, and re-collect dependencies.
*/
get () {
pushTarget(this)
let valueView on GitHub (pinned to 6c5d78ee04)
Solutions
- Fix the path to a simple dot-delimited string like 'a.b.c'
- Pass a function instead: watch the result of () => this.a[this.key].b for complex access
- Validate/trim the dynamic path string before constructing the watcher
- If the target may not exist, use a function returning the nested value safely
Example fix
// before
this.$watch('form.fields[' + i + '].value!', cb) // unparseable
// after
this.$watch(function () { return this.form.fields[i] && this.form.fields[i].value }, cb) Defensive patterns
Strategy: validation
Validate before calling
const SIMPLE_PATH_RE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*)*$/
function isValidWatchPath(p) { return typeof p === 'string' && SIMPLE_PATH_RE.test(p) }
// if (!isValidWatchPath(p)) pass a function instead Type guard
function isWatcherSource(s) { return typeof s === 'function' || isValidWatchPath(s) } Prevention
- Use only plain dot paths for string watch sources
- Prefer functions for dynamic or computed access paths
- Lint watch keys for typos like trailing dots or brackets
When it happens
Trigger: new Watcher(vm, 'a["b".c', ...) or any watch source with syntax parsePath cannot handle (brackets, invalid chars); watch: { 'items.': fn } typo; passing a path like 'a..b' or an expression like 'a + b' where a function is required; undefined/null passed as expOrFn.
Common situations: Typos in watch keys with trailing dots or stray brackets; using computed expressions in string form instead of a function; programmatic watcher creation from dynamic strings built at runtime.
Related errors
- You may have an infinite update loop in watcher with express
- Avoid mutating a prop directly since the value will be overw
- Avoid replacing instance root $data. Use nested data propert
- $props is readonly.
- Avoid mutating an injected value directly since the changes
AI-assisted analysis of Meituan-Dianping/mpvue@6c5d78ee04 (2026-09-02).
Data as JSON: /api/errors/09ae92aa99c96bf9.
Report an issue: GitHub.