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

  1. Convert the attribute to v-bind: v-bind:id="val" or the :id="val" shorthand
  2. Remove the mustaches and hardcode a static value if the attribute need not be dynamic
  3. 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

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


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