Task.synchronize() in coroutine leaks/breaks callback variable

Bug.rbxl (42.5 KB)

When I call task.synchronize() in a function which has been wrapped with coroutine.wrap(), the callback-function variable (returned by coroutine.wrap) has its value replaced with a leaking value (returned by the function that is wrapped).

In the attached Bug.rbxl, there is a Script in Workspace.Actor.Script. It defines a variable: local brokenVar = coroutine.wrap(a). When the script runs, it errors after 3 seconds due to the last line: brokenVar(), which errors: Attempt to call string value. brokenVar has no assignments to it after the first, so it should still be a function, but its value becomes whatever the function a returns.

This error only happens if there is a yield in a() after task.synchronize() is called, here task.wait(3).

Expected behavior

I expect the value of brokenVar to remain a function as it has had no other assignments to it. I also expect to get the value that the function a() yields/returns when calling brokenVar(), or an error ‘Cannot resume dead coroutine’, or a new error.

1 Like

Thank you for the report.

Error message is confusing, but it remains a function, nothing unexpected here.

This is not possible right now.

We recommend to not mix manual and task library coroutine management.
Resuming a coroutine registered to be resumed by engine causes this issue and others.
There might be an error for this in the future.

Overall this looks like attempt to use coroutine as a future/promise, you may want to look into the Luau promise libraries, for example roblox-lua-promise | roblox-lua-promise

1 Like