-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Bug: "An inline child actor cannot be persisted." error. #5057
Comments
You may find the error in the console output. |
Have you tried moving the actor to not be an inline actor, and instead be a referenced actor? |
I have the same problem, but after following your instructions, it is resolved now. |
Do you mind sharing the solution @remake99 ? Or @mkhsanov ? I'm getting the same error, but calling Here's my code sandbox. |
@davidkpiano how can it be a referenced actor? |
Is there a way to have a dynamic number of child actors based on the context that can actually be persisted? I have the same question as @hckhanh I can't seem to figure out how to create a referenced actor. I'm working on a game and I was hoping to have a parent actor that acts as authoritative server state and then individual child actors for each player. This is inside of a CloudFlare Durable Object so I'd like to be able to persist the state of the whole thing including parent and child machines into storage. |
@WonderPanda @reinoute I found out the answer. The referenced actor need to be declared in the setup function. Here is an example: export const mainTabLayoutMachine = setup({
types: {
context: {} as {
isTabDragging: boolean
tabGroupIds: string[]
tabGroups: ActorRefFrom<typeof mainTabGroupMachine>[][]
},
events: {} as
| { groupId: string; type: 'group.empty' }
| {
groupId: string
position: MainTabLayoutPosition
scope: MainTabLayoutScope
tabs: TabData[]
type: 'tabs.added'
}
| { type: 'tab.dragging' }
| { type: 'tab.dropped' },
},
actors: {
group: mainTabGroupMachine, // <--- declare it here
},
}).createMachine({
/* ... */
states: {
empty: {
on: {
'tabs.added': {
target: 'filled',
actions: assign({
tabGroups: ({ event, spawn }) => [
[spawn('group', { input: { tabs: event.tabs } })], // <-- make a call to the declared actor
],
tabGroupIds: [crypto.randomUUID()],
}),
},
},
},
},
/* ... */
}) |
Ahhh so this requires that the child actor is already instantiated before the setup phase of the parent. I was really hoping to be able to spawn children based on parent context and still have them be persistable. |
I think you should list all of them to the setup Functions. You can pass name to spawn children |
@hckhanh Unfortunately these are created dynamically so I can't list them ahead of time in the setup functions in my case. @davidkpiano I've just realized that this error only comes from the development build of XState. When I reference the main code instead, the error is not thrown and in all my tests the child actor state can be persisted and restored as expected. So this seems to be implemented. It makes sense to my naive brain that we just need to serialize Is there a reason we should avoid doing this? |
XState version
XState version 5
Description
In case if I try to create persisted snapshot with getPersistedSnapshot for actor which contains child spawned actors xstate raises an error.
Expected result
Crate persisted snapshot with child spawned actors.
Actual result
xstate raises an error with text "An inline child actor cannot be persisted."
Reproduction
https://codesandbox.io/p/live/47d8d896-243b-40a5-9a76-dafd43bb4847
Additional context
No response
The text was updated successfully, but these errors were encountered: