core icon indicating copy to clipboard operation
core copied to clipboard

"Hydration completed but contains mismatches" error not caught by the Vue error handler

Open claudiaballano opened this issue 8 months ago • 8 comments

Vue version

3.5

Link to minimal reproduction

https://play.vuejs.org/#__SSR__eNp9UstqwzAQ/BWhS1MINiHtJTiBNuTQQh+0PQqKsDeJU1kSergB43/vrl2noU1z0+7MSLM7aviNtUkdgc945nNX2sA8hGgXQpeVNS6wpaksWztTsYskpYLoFwe4MXrlnHFLaUN0UIyZg3X7LeiZQudG+8CAeGxOhJGOSl0S9Es+QhKbL1gjNOsFSS1VBJRhRU2pwAWiobztrsjS3jl6xiJAZZUMgBVjGRlO8ZilR30+5sGjp3W5SXbeaBy+e0/wHOklPvBkQ4meBZ/1TgiTSpnP+64XXITx0M+3kH+c6O/8nnqCPzvw4GoQ/IAF6TYQenj1+gh7PB/AyhRRIfsM+ALeqEgee9pt1AXaPuJ1bu+6jEq9efOrfQDth6HIKDHbji84BkWb+m/0H7vT5KrT4e5xi8N3OPF7htDLAqN7kGGbOKkLU40wsnOBbSeLpiFV22YpFn+je6/B0SD46DS5TiZT3n4BfWfvyQ==

Steps to reproduce

After this change, more hydration mismatch errors are appearing in production. However, Vue's error handlers are unable to catch them, likely because console.error is used directly instead of handleError.

Additionally, it would be helpful if these errors logged more contextual information rather than just a plain string, making debugging easier.

In the provided reproduction link, I introduced a random ID to force a hydration mismatch. However, Vue's error handler does not catch it. I also tested with app.config.errorHandler, but the issue persists.

What is expected?

Vue’s error handlers (onErrorCaptured and app.config.errorHandler) should be able to catch hydration mismatch errors, but they currently cannot, likely because console.error is used directly instead of handleError. Logging these errors through handleError would ensure they are properly intercepted, making it possible to handle them and provide better debugging insights.

What is actually happening?

Debugging becomes harder since it's just an string.

System Info


Any additional comments?

No response

claudiaballano avatar Apr 02 '25 20:04 claudiaballano

You can enable VUE_PROD_HYDRATION_MISMATCH_DETAILS to display details in the production build.

edison1105 avatar Apr 03 '25 02:04 edison1105

VUE_PROD_HYDRATION_MISMATCH_DETAILS

Yes @edison1105 , but this will only enable the warning. Our goal is to catch the errors and enrich them with more context. Imagine errors are being reported to an observability tool, they lack sufficient information for effective debugging.

claudiaballano avatar Apr 03 '25 07:04 claudiaballano

Any news on this? It would be so helpful if we can at least know from which component the error originated, we are basically blind.

arturmiglio avatar Jul 17 '25 07:07 arturmiglio

~~@claudiaballano I believe you should be able to use warning handling for this purpose, hydration warnings should be caught by this handler in prod if __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is enabled.~~

@arturmiglio __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ should indeed show the component name the hydration error originated from.

alex-snezhko avatar Oct 06 '25 02:10 alex-snezhko

@alex-snezhko VUE_PROD_HYDRATION_MISMATCH_DETAILS increases the bundle size, as noted in the official documentation. Additionally, the warnings only work in development mode, so this configuration is ignored in production. What we need is to monitor properly the errors in prod with additional context like owner + component trace. It would be nice to have this errors captured by onErrorCaptured and app.config.errorHandler.

claudiaballano avatar Oct 08 '25 09:10 claudiaballano

@claudiaballano Ah yes my apologies, my comment about the warnHandler catching these in prod was incorrect, I didn't see that this function is only ever invoked in dev mode which is necessary for warnHandler to work: https://github.com/vuejs/core/blob/079010a38cfff4c49e0a13e54ebff0c189a4d5dc/packages/runtime-core/src/warning.ts#L25-L27

Considering that this __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ flag already exists to explicitly enable warnings in production, I wonder if an alternative solution here could be to instead support warnHandler in prod mode for hydration mismatches rather than involving onErrorCaptured/errorHandler. The current hydration warnings published already include context as to what sort of mismatch was encountered and from which component, and in my opinion these hydration mismatches also feel more appropriate to classify as warnings rather than errors.

On the note of bundle size, this flag will indeed increase bundle size, though depending on the size of your project it may be comparatively small (well under 1%).

alex-snezhko avatar Oct 12 '25 07:10 alex-snezhko

@claudiaballano Ah yes my apologies, my comment about the warnHandler catching these in prod was incorrect, I didn't see that this function is only ever invoked in dev mode which is necessary for warnHandler to work:

core/packages/runtime-core/src/warning.ts

Lines 25 to 27 in 079010a

export function pushWarningContext(vnode: VNode): void { stack.push(vnode) } Considering that this __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ flag already exists to explicitly enable warnings in production, I wonder if an alternative solution here could be to instead support warnHandler in prod mode for hydration mismatches rather than involving onErrorCaptured/errorHandler. The current hydration warnings published already include context as to what sort of mismatch was encountered and from which component, and in my opinion these hydration mismatches also feel more appropriate to classify as warnings rather than errors.

On the note of bundle size, this flag will indeed increase bundle size, though depending on the size of your project it may be comparatively small (well under 1%).

Yes, this approach you're suggesting also makes sense! @alex-snezhko

claudiaballano avatar Oct 29 '25 16:10 claudiaballano

Enabling Vue’s internal hydration mismatch details flag __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ before app creation, then using a custom warnHandler just worked for me.

Image

ARZarkesh avatar Dec 15 '25 08:12 ARZarkesh