Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Cannot set parent: node already has a parent" #1000

Open
3 tasks
nvie opened this issue Jul 13, 2023 · 0 comments · Fixed by #1245
Open
3 tasks

"Cannot set parent: node already has a parent" #1000

nvie opened this issue Jul 13, 2023 · 0 comments · Fixed by #1245
Assignees
Labels
bug Something isn't working

Comments

@nvie
Copy link
Collaborator

nvie commented Jul 13, 2023

I created this ticket as a reference for anyone running into the following error:

Uncaught Error: Cannot set parent: node already has a parent

image

The issue

You can run into this runtime error when using @liveblocks/client or @liveblocks/react. This error is an internal integrity check that should never be surfaced to Liveblocks users, yet some people have seen it. It typically happens when you pass initialStorage like so:

const initialStorage = {
  animals: new LiveList(["🦊", "🐍", "🐻‍❄️"])
}

// If you use @liveblocks/client
client.enter(..., {
  initialStorage,
});

// If you use @liveblocks/react
<RoomProvider id="..." initialStorage={initialStorage}>...</RoomProvider>

The cause of the problem is that, on line 1, initialStorage is a global instance that instantiates the new LiveList (or LiveObject, or LiveMap) only once, and keeps a reference to the same instance, which gets reused between rooms when you leave/re-enter the room. This is problematic, because every Live data structure can only be bound to a room once, after that it "belongs" to that room instance. An attempt to reuse it in a different room later will fail — hence the "already has a parent" error message.

The fix

If you run into this issue, the fix is to pass a function as the initialStorage value, so new/unbound instances are created every time:

// ✅ Turn this into a factory!
const initialStorageFn = () => ({
  animals: new LiveList(["🦊", "🐍", "🐻‍❄️"])
});

// If you use @liveblocks/client
client.enter(..., {
  initialStorage: initialStorageFn,
});

// If you use @liveblocks/react
<RoomProvider id="..." initialStorage={initialStorageFn}>...</RoomProvider>

The real fixes

  • We should make the error message clearer and less obtuse
  • We should recommend the factory pattern in our documentation and examples by default
  • Maybe even deprecate passing a value directly, and always requiring a function?
@nvie nvie added bug Something isn't working triage needed The issue needs to be reviewed by the team labels Jul 13, 2023
@nvie nvie self-assigned this Jul 13, 2023
@nvie nvie removed the triage needed The issue needs to be reviewed by the team label Jul 13, 2023
@nvie nvie linked a pull request Oct 20, 2023 that will close this issue
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant