__main__ breaks Ray actors

1. Severity of the issue: (select one)
None: I’m just curious or want clarification.
Low: Annoying but doesn’t hinder my work.
[ x] Medium: Significantly affects my productivity but can find a workaround.
High: Completely blocks me.

2. Environment:

  • Ray version: 2.47.1
  • Python version: 3.12.8
  • OS: OS X
  • Cloud/Infrastructure: NA
  • Other libs/tools (if relevant):

3. What happened vs. what you expected:
The following code copied from the documentation runs.

import ray

@ray.remote
class Counter:
    def __init__(self):
        self.value = 0

    def increment(self):
        self.value += 1
        return self.value

    def get_counter(self):
        return self.value

counter = Counter.remote()

Here is the output.

2025-07-25 17:37:25,767	INFO worker.py:1723 -- Connecting to existing Ray cluster at address: 127.0.0.1:6379...
2025-07-25 17:37:25,774	INFO worker.py:1908 -- Connected to Ray cluster. View the dashboard at http://127.0.0.1:8265 

Then I do the same thing except inside a main function.

import ray

@ray.remote
class Counter:
    def __init__(self):
        self.value = 0

    def increment(self):
        self.value += 1
        return self.value

    def get_counter(self):
        return self.value


def main():
    counter = Counter.remote()


if __name__ == "__main__":
    main()

When run it I get the following.

2025-07-25 17:44:23,562	INFO worker.py:1723 -- Connecting to existing Ray cluster at address: 127.0.0.1:6379...
2025-07-25 17:44:23,569	INFO worker.py:1908 -- Connected to Ray cluster. View the dashboard at http://127.0.0.1:8265 
[2025-07-25 17:44:23,631 E 35409 33058428] core_worker.cc:2730: Failed to register actor. Error message: SchedulingCancelled: Actor creation cancelled. actor_id=c608c3f4f09fe5bf3ab2a1301c000000

Is this expected? The if __name__ == "__main__" idiom should never break anything.

[Edit]

Ok, I don’t see this problem if a pause for a couple seconds after making the remote call. Is this expected behavior when the remote actor goes out of scope too quickly?

Hello! If the reference to it goes out of scope (such as at the end of your main() function), Ray will garbage collect the actor, which can result in the “Actor creation cancelled” error if the process exits before the actor is fully registered or started. So that’s why the pause helps too. This article on actors might help, they talk about it a bit? Actors — Ray 2.48.0

And here specifically: Terminating Actors — Ray 2.48.0

Actor processes will be terminated automatically when all copies of the actor handle have gone out of scope in Python, or if the original creator process dies.