Skip to content

fix: keep onCleanup order consistent between dev and prod#2710

Open
ATOM00blue wants to merge 2 commits into
solidjs:mainfrom
ATOM00blue:fix/dev-owner-consistency
Open

fix: keep onCleanup order consistent between dev and prod#2710
ATOM00blue wants to merge 2 commits into
solidjs:mainfrom
ATOM00blue:fix/dev-owner-consistency

Conversation

@ATOM00blue
Copy link
Copy Markdown

Summary

In dev builds, components are wrapped in an extra owner scope by devComponent so devtools can observe component boundaries. This wrapper does not exist in production, which caused onCleanup callbacks registered directly in a component body to fire in a different order on disposal than in production.

This registers such cleanups on the same owner they would be in production by skipping past any dev component wrapper(s). The owner returned by getOwner() inside a component is intentionally left unchanged, so devtools continues to see the component owner.

Test plan

  • New tests in dev.spec.ts assert dev onCleanup order matches prod for sibling, nested, and re-created component cases
  • Existing solid package test suite shows no new failures

Closes #1561

In dev builds, components are wrapped in an extra owner scope by
`devComponent` so devtools can observe component boundaries. This wrapper
does not exist in production, which caused `onCleanup` callbacks registered
directly in a component body to fire in a different order on disposal than
in production.

Register such cleanups on the same owner they would be in production by
skipping past any dev component wrapper(s). The component owner returned by
`getOwner()` is left unchanged so devtools still works.

Closes solidjs#1561
Copilot AI review requested due to automatic review settings May 21, 2026 02:35
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 21, 2026

🦋 Changeset detected

Latest commit: a4dba97

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
solid-js Patch
test-integration Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Ensures onCleanup callback disposal order remains consistent between dev and production by skipping dev-only component wrapper owners when registering cleanups (fixing Solid issue #1561), and adds regression tests to lock in the expected behavior.

Changes:

  • Update onCleanup to register callbacks on the same owner chain as production by skipping dev component wrapper owner(s).
  • Add dev-only tests for cleanup ordering, nested components, re-creation behavior, and getOwner expectations.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/solid/test/dev.spec.ts Adds regression tests that compare dev vs simulated-production cleanup order and related owner behavior.
packages/solid/src/reactive/signal.ts Adjusts onCleanup owner selection in dev to avoid dev wrapper affecting cleanup ordering.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// which means cleanups registered directly in a component body would otherwise
// be ordered differently on disposal. Skip past any dev component wrapper(s) so
// the cleanup is registered on the same owner it would be in production. See #1561.
if (IS_DEV) while (o && (o as DevComponent<any>).component) o = o.owner;
Comment on lines +206 to +216
// Simulate the production code path (no dev wrapper) by calling the
// component directly under `untrack`, like `createComponent` does in prod.
const prodOrder: string[] = [];
createRoot(dispose => {
onCleanup(() => prodOrder.push("before"));
untrack(() =>
(function Child() {
onCleanup(() => prodOrder.push("child"));
return null;
})()
);
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.

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

2 participants