Meituan-Dianping/mpvue · error
${name}="${value}": Interpolation inside attributes has been
Error message
${name}="${value}": Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of <div id="{{ val }}">, use <div :id="val">. What it means
Mustache interpolation ({{ }}) inside a plain (non-v-bind) attribute is no longer supported: attributes are string literals and cannot receive reactive updates. The compiler detects interpolation via parseText and warns, telling you to use v-bind or the : shorthand so the attribute compiles to a dynamic binding.
Source
Thrown at packages/weex-template-compiler/build.js:1826
} else { // normal directives
name = name.replace(dirRE, '');
// parse arg
var argMatch = name.match(argRE);
var arg = argMatch && argMatch[1];
if (arg) {
name = name.slice(0, -(arg.length + 1));
}
addDirective(el, name, rawName, value, arg, modifiers);
if (process.env.NODE_ENV !== 'production' && name === 'model') {
checkForAliasModel(el, value);
}
}
} else {
// literal attribute
if (process.env.NODE_ENV !== 'production') {
var expression = parseText(value, delimiters);
if (expression) {
warn(
name + "=\"" + value + "\": " +
'Interpolation inside attributes has been removed. ' +
'Use v-bind or the colon shorthand instead. For example, ' +
'instead of <div id="{{ val }}">, use <div :id="val">.'
);
}
}
addAttr(el, name, JSON.stringify(value));
}
}
}
function checkInFor (el) {
var parent = el;
while (parent) {
if (parent.for !== undefined) {
return true
}View on GitHub (pinned to 6c5d78ee04)
Solutions
- Convert the attribute to v-bind: v-bind:id="val" or the :id="val" shorthand
- Remove the mustaches and hardcode a static value if the attribute need not be dynamic
- Sweep legacy templates for attribute="{{ }}" patterns when migrating from Vue 1
Example fix
// before
<div id="{{ val }}">
// after
<div :id="val"> Defensive patterns
Strategy: validation
Validate before calling
function attrInterpolation(template) {
// matches attributes whose value contains {{ }} but no v-bind prefix
const re = /(?<!v-[:a-z])\s([\w-]+)="[^"]*\{\{[^}]*\}\}[^"]*"/g;
const bad = [];
let m;
while ((m = re.exec(template))) bad.push(`${m[1]}="${m[0].match(/"[^"]*"/)[0]}"`);
return bad;
} Type guard
function hasNoAttrInterpolation(template) {
return typeof template === 'string' && attrInterpolation(template).length === 0;
} Prevention
- Always use :attr="expr" (v-bind) for dynamic attribute values
- Sweep legacy Vue 1 / Handlebars templates for attr="{{ }}" before migrating
- Enable eslint-plugin-vue's no-mustache-in-attribute style checks
When it happens
Trigger: Writing an attribute like id="{{ val }}" or href="{{ url }}" without v-bind, so in the attribute handling path parseText(value, delimiters) returns an expression and dev-mode warn fires.
Common situations: Upgrading from Vue 1.x where attribute interpolation was legal (a common 1.x → 2.x migration break), or copying HTML from other templating engines (Handlebars-style) into Vue templates.
Related errors
- tag <${tag}> has no matching end tag.
- Templates should only be responsible for mapping the state t
- <template> cannot be keyed. Place the key on real elements i
- Invalid v-for expression: ${exp}
- v-${el.elseif ? ('else-if="' + el.elseif + '"') : 'else'} us
AI-assisted analysis of Meituan-Dianping/mpvue@6c5d78ee04 (2026-09-02).
Data as JSON: /api/errors/631ae09fba83865b.
Report an issue: GitHub.