Skip to content

fix(devtools-kit): only treat own render property as component definition#1110

Open
lazerg wants to merge 3 commits into
vuejs:mainfrom
lazerg:fix/pinia-unknown-component
Open

fix(devtools-kit): only treat own render property as component definition#1110
lazerg wants to merge 3 commits into
vuejs:mainfrom
lazerg:fix/pinia-unknown-component

Conversation

@lazerg

@lazerg lazerg commented Jul 2, 2026

Copy link
Copy Markdown

Fixes #1100.

As @skirtles-code pointed out in the issue, the state serializer treats any object with a render method as a Vue component definition, so plain class instances stored in Pinia state (whose class happens to define a render method) are shown as "Unknown component". A component definition keeps render as an own property, whereas a class instance inherits it from the prototype, so this checks for an own render property — real component definitions are still detected, and ordinary objects are left alone.

@netlify

netlify Bot commented Jul 2, 2026

Copy link
Copy Markdown

Deploy Preview for vue-devtools-docs canceled.

Name Link
🔨 Latest commit 90b52fa
🔍 Latest deploy log https://app.netlify.com/projects/vue-devtools-docs/deploys/6a5c2e800b39190008a78efc

@lazerg

lazerg commented Jul 6, 2026

Copy link
Copy Markdown
Author

@skirtles-code you'd already pinpointed the line on this one, mind checking if the own-property guard matches what you had in mind?

@skirtles-code skirtles-code left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't really have a specific fix in mind when I posted that comment.

There is no totally reliable way to detect a component, but using hasOwnProperty is an interesting idea. Components can, in theory, inherit a render property via their prototype chain, but I'm not sure whether that's common enough to worry about.

One thought that occurs is that components are plain (non-reactive) objects, so I wonder whether we can take advantage of that to improve the detection heuristics?

@lazerg

lazerg commented Jul 18, 2026

Copy link
Copy Markdown
Author

took a look at how render actually ends up on component definitions in practice. Plain options objects and defineComponent() assign it directly ({ render() {...} }). Compiled SFCs do the same—the compiler puts _sfc_main.render = render on the exported object instead of the prototype. So for the two main ways people author Vue 3 components today, it always lands as an own property.

I can't completely rule out some old class-component library doing it differently, but that's rare enough in current Vue 3 code that it's not worth designing around.

The reactive vs. plain object idea is a good one. There's already an isReactive() helper in is.ts (the same file isVueInstance is imported from): !!raw.__v_isReactive. Component definitions are never wrapped in reactive(), but Pinia state—the actual source of this bug—always is. So !isReactive(val) would catch the false positive at the root instead of relying only on the render shape.


I can add that as an extra condition next to the hasOwnProperty check if it sounds good to you. It's basically a one-line change since the helper is already there.

@skirtles-code

Copy link
Copy Markdown
Contributor

Yeah, I think adding an isReactive check would be a good idea.

@lazerg

lazerg commented Jul 19, 2026

Copy link
Copy Markdown
Author

Added the isReactive check and pushed it up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"Unknown component" in Pinia devtools

2 participants