Meituan-Dianping/mpvue · warning
<select multiple v-model="${binding.expression}"> expects an
Error message
<select multiple v-model="${binding.expression}"> expects an Array value for its binding, but got ${Object.prototype.toString.call(value).slice(8, -1)} What it means
For `<select multiple v-model>`, the v-model directive's setSelected routine expects the bound value to be an Array (one entry per selected option). When the binding value is any other type (string, number, object, undefined), Vue warns in development, naming the expression and the actual type via Object.prototype.toString, because option matching against the value would fail.
Source
Thrown at src/platforms/web/runtime/directives/model.js:73
// in case the options rendered by v-for have changed,
// it's possible that the value is out-of-sync with the rendered options.
// detect such cases and filter out values that no longer has a matching
// option in the DOM.
const needReset = el.multiple
? binding.value.some(v => hasNoMatchingOption(v, el.options))
: binding.value !== binding.oldValue && hasNoMatchingOption(binding.value, el.options)
if (needReset) {
trigger(el, 'change')
}
}
}
}
function setSelected (el, binding, vm) {
const value = binding.value
const isMultiple = el.multiple
if (isMultiple && !Array.isArray(value)) {
process.env.NODE_ENV !== 'production' && warn(
`<select multiple v-model="${binding.expression}"> ` +
`expects an Array value for its binding, but got ${
Object.prototype.toString.call(value).slice(8, -1)
}`,
vm
)
return
}
let selected, option
for (let i = 0, l = el.options.length; i < l; i++) {
option = el.options[i]
if (isMultiple) {
selected = looseIndexOf(value, getValue(option)) > -1
if (option.selected !== selected) {
option.selected = selected
}
} else {
if (looseEqual(getValue(option), value)) {View on GitHub (pinned to 6c5d78ee04)
Solutions
- Initialize the v-model binding as an empty array: `selected: []`.
- Normalize server/async data before assigning, e.g. `this.selected = Array.isArray(raw) ? raw : raw ? [raw] : []`.
- If a computed supplies the value, make sure every return path yields an array.
- When converting from single to multiple select, update the model shape alongside the template.
Example fix
// before
data: { selected: null }
<select multiple v-model="selected">...
// after
data: { selected: [] }
<select multiple v-model="selected">... Defensive patterns
Strategy: type-guard
Validate before calling
if (!Array.isArray(form.selectedOptions)) {
form.selectedOptions = []
} Type guard
function isArrayBinding(v) {
return Array.isArray(v)
} Prevention
- Initialize multiple-select v-model state as [] not null/''/undefined.
- Normalize API payloads to arrays before assigning to the model.
- Ensure computeds feeding a multiple select always return arrays.
- When toggling `multiple` on a select, change the model type at the same time.
When it happens
Trigger: Binding a non-array to a multiple select: `v-model="selected"` where selected is initialized to `''`, `null`, a number, or an object; receiving server data where the field is a single value instead of a list; using a computed that sometimes returns a scalar.
Common situations: Form initialization before async data loads (value is undefined/null at componentUpdated time); switching a single-select to `multiple` without changing the model from string to array; API responses that return a comma-separated string for multi-select fields.
Related errors
- <input :type="${dynamicType}" v-model="${value}">: v-model d
- <${el.tag} v-model="${value}" type="file">: File inputs are
- <${el.tag} v-model="${value}">: v-model is not supported on
- tag <${tag}> has no matching end tag.
- [Vue tip]: ${msg}
AI-assisted analysis of Meituan-Dianping/mpvue@6c5d78ee04 (2026-09-02).
Data as JSON: /api/errors/ba57d01d389dab07.
Report an issue: GitHub.