{"record":{"id":"c9b1555017590385","repo":"Meituan-Dianping/mpvue","slug":"attrs-is-readonly","errorCode":null,"errorMessage":"$attrs is readonly.","messagePattern":"\\$attrs is readonly\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/core/instance/render.js","lineNumber":55,"sourceCode":"  const renderContext = parentVnode && parentVnode.context\n  vm.$slots = resolveSlots(vm.$options._renderChildren, renderContext)\n  vm.$scopedSlots = emptyObject\n  // bind the createElement fn to this instance\n  // so that we get proper render context inside it.\n  // args order: tag, data, children, normalizationType, alwaysNormalize\n  // internal version is used by render functions compiled from templates\n  vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)\n  // normalization is always applied for the public version, used in\n  // user-written render functions.\n  vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)\n\n  // $attrs & $listeners are exposed for easier HOC creation.\n  // they need to be reactive so that HOCs using them are always updated\n  const parentData = parentVnode && parentVnode.data\n  /* istanbul ignore else */\n  if (process.env.NODE_ENV !== 'production') {\n    defineReactive(vm, '$attrs', parentData && parentData.attrs, () => {\n      !isUpdatingChildComponent && warn(`$attrs is readonly.`, vm)\n    }, true)\n    defineReactive(vm, '$listeners', parentData && parentData.on, () => {\n      !isUpdatingChildComponent && warn(`$listeners is readonly.`, vm)\n    }, true)\n  } else {\n    defineReactive(vm, '$attrs', parentData && parentData.attrs, null, true)\n    defineReactive(vm, '$listeners', parentData && parentData.on, null, true)\n  }\n}\n\nexport function renderMixin (Vue: Class<Component>) {\n  Vue.prototype.$nextTick = function (fn: Function) {\n    return nextTick(fn, this)\n  }\n\n  Vue.prototype._render = function (): VNode {\n    const vm: Component = this\n    const {","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/Meituan-Dianping/mpvue/blob/6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b/src/core/instance/render.js#L37-L73","documentation":"Comes from the dev-only setter trap placed on the $attrs property during initRender. $attrs (the container element attributes passed down to a component) is defined with a getter only and is meant to be read — primarily for higher-order-component pass-through via v-bind=\"$attrs\". Assigning to it (this.$attrs = ...) hits this trap; the framework manages $attrs internally from the parent vnode's data on every parent re-render, so user writes to it are rejected.","triggerScenarios":"Thrown at src/core/instance/render.js:55 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Remove any assignment to this.$attrs; treat it as read-only","To alter attributes on the root element, set normal attributes on the component's root node or use attrs in the component's own template","If you need a mutable copy, clone it into data: data() { return { attrs: { ...this.$attrs } } }"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b","analyzedAt":"2026-09-02T05:17:40.946Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T11:17:12.671Z"}