Meituan-Dianping/mpvue · warning
invalid template option:${template}
Error message
invalid template option:${template} What it means
Vue's $mount with the runtime-with-compiler build resolves the `template` option by trying selector string, innerHTML string, or DOM node. If the template option is set to something none of these branches can handle (e.g. a number, function, boolean, or null when el is also absent), the compiler cannot proceed and warns 'invalid template option'. The library throws it because a template it cannot interpret means it cannot produce a render function.
Source
Thrown at src/platforms/web/entry-runtime-with-compiler.js:52
if (!options.render) {
let template = options.template
if (template) {
if (typeof template === 'string') {
if (template.charAt(0) === '#') {
template = idToTemplate(template)
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && !template) {
warn(
`Template element not found or is empty: ${options.template}`,
this
)
}
}
} else if (template.nodeType) {
template = template.innerHTML
} else {
if (process.env.NODE_ENV !== 'production') {
warn('invalid template option:' + template, this)
}
return this
}
} else if (el) {
template = getOuterHTML(el)
}
if (template) {
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
mark('compile')
}
const { render, staticRenderFns } = compileToFunctions(template, {
shouldDecodeNewlines,
delimiters: options.delimiters,
comments: options.comments
}, this)
options.render = renderView on GitHub (pinned to 6c5d78ee04)
Solutions
- Ensure `template` is either a string (selector starting with '#', or an HTML string) or a DOM element (has nodeType).
- If you meant to render a component, register it via `components` and use it in the template, not as the template value.
- If the template comes from a variable, check it is defined and is a string before mounting.
- If you don't need a template, remove the option and use `render: h => h(...)` instead (runtime-only builds don't compile templates anyway).
Example fix
// before
new Vue({ template: myComponent, el: '#app' })
// after
new Vue({
el: '#app',
components: { myComponent },
template: '<my-component/>'
}) Defensive patterns
Strategy: validation
Validate before calling
const opts = { template: myTemplate }
const isValidTemplate = t => typeof t === 'string' || (t && typeof t.nodeType === 'number')
if (!isValidTemplate(opts.template)) {
throw new TypeError('template option must be a selector/HTML string or a DOM node, got: ' + typeof opts.template)
} Type guard
function isValidTemplate(t) {
return typeof t === 'string' || (t != null && typeof t.nodeType === 'number')
} Prevention
- Only pass strings or DOM nodes to the template option.
- Use `render` functions with the runtime-only build where template compilation isn't available.
- Register sub-components via `components` instead of assigning them as `template`.
- Log the template value right before mounting when it comes from dynamic sources.
When it happens
Trigger: Calling `new Vue({ template: <non-string, non-node> })` then `$mount()`, e.g. `template: 123`, `template: someComponent`, `template: null`, or passing a compiled render template object instead of a string/DOM element.
Common situations: Passing a Vue component object as `template` instead of putting it in `components`; typos like `template: this.someTemplate` where the value is undefined at mount time; using the runtime-only build where the compiler entry path differs; migrating from templates to render functions and leaving a stale template value.
Related errors
- Use "contextmenu" instead of "click.right" since right click
- 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}
AI-assisted analysis of Meituan-Dianping/mpvue@6c5d78ee04 (2026-09-02).
Data as JSON: /api/errors/7e264b6449b756b0.
Report an issue: GitHub.