You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
inconsistent owner in Component function (production vs development build) result in out of order onCleanup #1561
A component function owner is different between a dev and prod build
functionMyComponent(){getOwner()// <-- this is different between prod/dev builds.// in prod the owner is of the parent, in dev it is a new owner scope.return<></>}
this inconsistency causes unexpected behavior, for example when using solid's onCleanup primitive
changed the title [-]inconsistent owner in Component function (product vs development build)[/-][+]inconsistent owner in Component function (production vs development build)[/+]on Feb 17, 2023
If you're using the Vite plugin (or any plugin that is using Solid Refresh), this is by design. The reason is because Solid Refresh wraps the component into a memo managed by proxy HMR component. You're always going to get the owner that is provided by the memo.
edit:
seems like the discord thread is referring to some other issue.
changed the title [-]inconsistent owner in Component function (production vs development build)[/-][+]inconsistent owner in Component function (production vs development build) result in out of order onCleanup [/+]on Feb 17, 2023
yes, onCleanup is one of the bug we know of that is caused by this extra wrapping
in this case, is it the dev wrapper that is added in dev build, but it is very much possible that the hmr wrapper will cause similar issues, so it is perhaps something to consider when designing a general fix for this.
@thetarnav and I looked into possible fixes, we tested this as a fix
what I did is resolve the parent if the component is marked as a dev component.
then restore the owner at the end.
isHMROwner => isDevOwner
I did a minimal in browser patching, and it seem to correct the order with the very basic use case.
I am not sure if onCleanup is the only place we want/need this, but it is a start
I was playing around with something similar. At first I simply tried to hoist up the owner in devComponent, but obviously that would break DevTools. The whole point is to inject the owner.
Was this approach enough to get back out... because if I remember HMR also wraps things.. is it a Memo or Signal? If it is a signal that is fine. But if it is a Memo then we have another owner in here.
Thanks for digging into this. We're going to close this rather than change the behavior in 1.x.
Where dev and prod actually differ
When an owner is disposed, Solid 1.x always tears down everything it owns (effects, memos, child scopes) before running that owner's own onCleanup callbacks. As a result:
onCleanup inside an effect or memo belongs to that computation, and it tears down in the same order in dev and prod.
A component's own effects are always cleaned up before its body-level onCleanup, in both builds.
The only difference is the order of body-levelonCleanupacross components. In dev, devComponent gives each component its own owner, so its body cleanups run with the rest of that component's teardown. In prod, body cleanups are registered on the parent owner, so they run after all of the parent's owned computations, including sibling components' effects.
Why we're not changing it
Making dev move body cleanups to the parent owner only partly helps. Under hot reload, Solid Refresh adds another owner of its own, so dev still wouldn't match prod. It would also take those cleanups off the component's owner in devtools. We've never guaranteed teardown order between sibling components, and we reached the same conclusion for 2.0 in #3591, which documents the dev/prod difference rather than trying to remove it.
Guidance: if teardown order matters, register the cleanup in the effect or computation that owns the resource. Don't rely on the relative order of body-level onCleanup between different components.
Activity
[-]inconsistent owner in Component function (product vs development build)[/-][+]inconsistent owner in Component function (production vs development build)[/+]lxsmnsyc commentedon Feb 17, 2023
If you're using the Vite plugin (or any plugin that is using Solid Refresh), this is by design. The reason is because Solid Refresh wraps the component into a memo managed by proxy HMR component. You're always going to get the owner that is provided by the memo.
edit:
seems like the discord thread is referring to some other issue.
thetarnav commentedon Feb 17, 2023
Yeah, the issue is mostly about the order of
onCleanupcalls in dev vs prod. Probably should be titled better.[-]inconsistent owner in Component function (production vs development build)[/-][+]inconsistent owner in Component function (production vs development build) result in out of order onCleanup [/+]LiQuidProQuo commentedon Feb 17, 2023
yes,
onCleanupis one of the bug we know of that is caused by this extra wrappingin this case, is it the dev wrapper that is added in dev build, but it is very much possible that the hmr wrapper will cause similar issues, so it is perhaps something to consider when designing a general fix for this.
ryansolid commentedon Feb 19, 2023
I guess the fix is to exempt it as an owner. Have the parent still own everything. That seems doable.
LiQuidProQuo commentedon Feb 19, 2023
@thetarnav and I looked into possible fixes, we tested this as a fix
what I did is resolve the parent if the component is marked as a dev component.
then restore the owner at the end.
isHMROwner => isDevOwnerI did a minimal in browser patching, and it seem to correct the order with the very basic use case.
I am not sure if
onCleanupis the only place we want/need this, but it is a startryansolid commentedon Feb 20, 2023
I was playing around with something similar. At first I simply tried to hoist up the owner in
devComponent, but obviously that would break DevTools. The whole point is to inject the owner.Was this approach enough to get back out... because if I remember HMR also wraps things.. is it a Memo or Signal? If it is a signal that is fine. But if it is a Memo then we have another owner in here.
fix: keep onCleanup order consistent between dev and prod
ryansolid commentedon Oct 6, 2026
Thanks for digging into this. We're going to close this rather than change the behavior in 1.x.
Where dev and prod actually differ
When an owner is disposed, Solid 1.x always tears down everything it owns (effects, memos, child scopes) before running that owner's own
onCleanupcallbacks. As a result:onCleanupinside an effect or memo belongs to that computation, and it tears down in the same order in dev and prod.onCleanup, in both builds.onCleanupacross components. In dev,devComponentgives each component its own owner, so its body cleanups run with the rest of that component's teardown. In prod, body cleanups are registered on the parent owner, so they run after all of the parent's owned computations, including sibling components' effects.Why we're not changing it
Making dev move body cleanups to the parent owner only partly helps. Under hot reload, Solid Refresh adds another owner of its own, so dev still wouldn't match prod. It would also take those cleanups off the component's owner in devtools. We've never guaranteed teardown order between sibling components, and we reached the same conclusion for 2.0 in #3591, which documents the dev/prod difference rather than trying to remove it.
Guidance: if teardown order matters, register the cleanup in the effect or computation that owns the resource. Don't rely on the relative order of body-level
onCleanupbetween different components.