Skip to content

inconsistent owner in Component function (production vs development build) result in out of order onCleanup  #1561

Closed as not planned

Description

@LiQuidProQuo

Describe the bug

A component function owner is different between a dev and prod build

function MyComponent(){
     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

dev build playground
image

production build playground

image

note: production build is working as designed, it is dev that alters the expectations

Your Example Website or App

.

Steps to Reproduce the Bug or Issue

see playground links for the difference between dev and prod

Expected behavior

it is expected that dev and prod will work similarly, in regard to owner scopes.

Screenshots or Videos

No response

Platform

.

Additional context

No response

related discussion of the issue
https://discord.com/channels/722131463138705510/1075879661134942238

Activity

  1. 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
  2. lxsmnsyc commented on Feb 17, 2023

    @lxsmnsyc
    Member

    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.

  3. thetarnav commented on Feb 17, 2023

    @thetarnav
    Contributor

    Yeah, the issue is mostly about the order of onCleanup calls in dev vs prod. Probably should be titled better.

  4. 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
  5. LiQuidProQuo commented on Feb 17, 2023

    @LiQuidProQuo
    ContributorAuthor

    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.

  6. ryansolid commented on Feb 19, 2023

    @ryansolid
    Member

    I guess the fix is to exempt it as an owner. Have the parent still own everything. That seems doable.

  7. LiQuidProQuo commented on Feb 19, 2023

    @LiQuidProQuo
    ContributorAuthor

    @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.

    image

    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

  8. ryansolid commented on Feb 20, 2023

    @ryansolid
    Member

    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.

  9. added
    PRs WelcomeAn issue which might not be prioritized right away but would be open to community contribution
    on May 24, 2023
  10. added a commit that references this issue on May 21, 2026
    49bdc24
  11. ryansolid commented on Oct 6, 2026

    @ryansolid
    Member

    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-level onCleanup across 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.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    PRs WelcomeAn issue which might not be prioritized right away but would be open to community contributionbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions