diff --git a/rivetkit-rust/packages/rivetkit-core/src/registry/mod.rs b/rivetkit-rust/packages/rivetkit-core/src/registry/mod.rs index 396ec5158b..3bf20980cc 100644 --- a/rivetkit-rust/packages/rivetkit-core/src/registry/mod.rs +++ b/rivetkit-rust/packages/rivetkit-core/src/registry/mod.rs @@ -1143,23 +1143,28 @@ impl RegistryDispatcher { } let mut join_guard = instance.join.lock().await; - if let Some(join) = join_guard.take() { + // Fold the join outcome into the result instead of propagating with `?`, + // so the stop handle is always signaled and never dropped unsignaled. + let join_result = if let Some(join) = join_guard.take() { join.await - .context("join actor task")? - .context("actor task failed")?; - } + .context("join actor task") + .and_then(|result| result.context("actor task failed")) + } else { + Ok(()) + }; instance.ctx.configure_lifecycle_events(None); - match shutdown_result { + let final_result = shutdown_result.and(join_result); + match &final_result { Ok(_) => { let _ = stop_handle.complete(); - Ok(()) } Err(error) => { - let _ = stop_handle.fail(anyhow::Error::new(RivetError::extract(&error))); - Err(error).with_context(|| format!("stop actor `{actor_id}`")) + let _ = stop_handle.fail(anyhow::Error::new(RivetError::extract(error))); } } + + final_result.with_context(|| format!("stop actor `{actor_id}`")) } }