Cannot resume dead coroutine despite it being a new coroutine

local function Scan(...)
	-- ...
	for _, _ in pairs(...) do
		-- ...
	end
end
local ScanProcess = nil
function ButtonPressed()
	if ScanProcess then
		coroutine.close(ScanProcess)
		ScanProcess = nil
	end
	ScanProcess = coroutine.create(Scan)
	coroutine.resume(ScanProcess)
end

Why am I getting image error? I don’t understand it since coroutine is being resumed when a new one is already created and set to the variable. This error only happens when I start a long scan process and right after I press scan button again for a short scan.

13 Likes

Seems like a bug as you mentioned. I was unable to replicate by copy and pasting @Halalaluyafail3 code

Replication code
local co = coroutine.create(function()
	while true do
		print(1)
		task.wait()
	end
end)
coroutine.resume(co) -- start printing 1 every frame
task.wait(2)
coroutine.close(co) -- stop printing every frame

local co = coroutine.create(function()
	while true do
		print(1)
		task.wait()
	end
end)
coroutine.resume(co) -- start printing 1 every frame
task.wait(2)
coroutine.close(co) -- stop printing every frame

Maybe something funky happened with the task scheduler during this long scan process? There was a similar bug with task.wait()

1 Like

Perhaps? I have task.wait() in my scan function.

for i, inst in pairs(...) do
	pcall(function()
		-- ...
		if i % 1000 == 0 and i ~= 0 then
			task.wait()
		end
	end)
end

The process is like this:

  1. I request a long scan with a button press
  2. Coroutine is created
  3. Coroutine is resumed
  4. I request a short scan with a button press in middle of the previous scan
  5. Previous coroutine is closed
  6. Previous coroutine variable is set to nil
  7. New coroutine is created
  8. New coroutine is resumed

And error occurs.

1 Like

ScanProcess should be specifically checked if it is not nil.
It will proceed to close the coroutine if you don’t check for nil because ScanProcess can also be false.

local ScanProcess = nil
function ButtonPressed()
    if ScanProcess ~= nil then
        coroutine.close(ScanProcess)
    end

    ScanProcess = coroutine.create(Scan)
    coroutine.resume(ScanProcess)
end

Other than that, I’d check for some similar information here:

1 Like

Unfortunately it doesn’t fix the issue.

Am I suppose to try coroutine.wrap()? If so can I close it like with coroutine.create() method?

1 Like

It would be optimal to use coroutine.create() and coroutine.resume() rather than coroutine.wrap(), since it would return extra arguments, but you can clear those by overwriting ScanProcess to nil.

Is there any other function that’s causing ScanProcess to be other than nil? A dead coroutine could return as a return but also an error. Perhaps there is an error within Scan(), did you try running Scan() without the coroutine?

1 Like

Nope.

Nope.

image

The weird thing is that I always get “suspended” status but despite that fact I still get “cannot resume dead coroutine” error.

ScanProcess = coroutine.create(Scan)
print(coroutine.status(ScanProcess))
coroutine.resume(ScanProcess)

The odd thing is how a coroutine is being “resumed” while “dead” if it’s never “dead” just a line before resuming it. Also pcall() for some reason cannot suppress this error.

1 Like

I have a script with a similar purpose and I am getting the same error.

  1. Coroutine is created
  2. Coroutine is resumed
  3. Coroutine is functioning
  4. Coroutine is closed
  5. Coroutine is set to nil in table

Currently don’t know how to fix it and will be waiting for a solution to this.

1 Like

Can reproduce this, I have a script that creates a new coroutine, resumes it, closes it, redefines a new instance of the same coroutine in the same variable, resumes it, and gets this error.

4 Likes

Have you guys found out the Problem? i am currently in the same Position as you guys

1 Like
function module:Run(goal)
	local path = self.path

	self:Stop()

	self:Compute(goal)
	self.waypoints = path:GetWaypoints()

	self.thread = task.spawn(self.Follow, self)
end

I’m experiencing the same or a very similar issue. In this case the self:Stop() checks if self.thread exists, and then calls task.cancel on it if it does. And you can see at the bottom of the function above, it then replaces the thread with a newly created one.

(note that this happens regardless of if self.Follow is changed to a functional literal or not)

1 Like

Same thing here!
I had no issues with bread & butter tasks like these back in 2018.

A stack trace for this error would be nice while we’re at it.
The feedback is a real headscratcher when you work with multiple coroutine creations in a single module.
Wouldn’t be surprised if the person who wrote the message was in a hurry judging by how short, undescriptive, and unformatted it is :laughing:

image

3 Likes

If you guys are using a while or for, possibly using RunService like Heartbeat and disconnecting it once done and assigning it to the variable again could fix this error. This concept is very similar to what the author here is trying to do.

1 Like

Still experiencing this error in Aug 2023 with logic similar to this

1 Like

Just stumbled upon this bug. Having a coroutine with RBXScriptConnection:Wait() get cancelled is what seems to cause this. In particular, I’m using promises. My guess is the task scheduler just doesn’t realize that the coroutine that’s waiting for the connection to fire is already dead…

For me, this doesn’t break anything - the error is outputted but my code runs as expected. Hopefully this can get fixed soon because it’s pretty annoying!

1 Like

I also experience this. I am trying my best at fixing this issue and so far no luck. What the hell?

Ah, yes this is an overdue answer, but I will try to answer the best that I can.

This is an issue that’s related to how computer memory allocation and multithreading works. When you create a coroutine thread in Roblox, a hash value is created in the heap memory. This hash value is used to store data in a different address space. When you try to call a value from a different thread, it won’t work because it’s written in a different namespace and environment / scope.

In the case of Luau coroutines, I’d have to theorize that every time a coroutine is created, it will be written in a different heap memory or address location that’s not available in parallel because every time you try to get the coroutine result, it would return as nil or not work at all. I’d like for someone to prove this idea wrong, but this is as far as I know from researching hashing algorithms.

A solution for this: Switch to task.spawn() because the task manager keeps track of the memory allocations and is reliable at returning a result.

task.spawn() will still do the same error, I’ve tested it both task and coroutine.

Again, I recommend doing this, as I have already stated in this post. Try as best to use like RunService and just :Disconnect() it and the error shouldn’t be popping up.