ros2
actions
ai_generated
true
ROS2 action goal preemption causes crash or undefined behavior when new goal arrives during execution
ID: ros2/action-server-preemption-race
85%Fix Rate
88%Confidence
3Evidence
2023-01-01First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| any | active | — | — | — |
Root Cause
ROS2 action servers don't automatically handle goal preemption. When a new goal arrives while executing a previous one, both execute concurrently unless you explicitly implement preemption logic in handle_goal and execute callbacks.
genericWorkarounds
-
90% success Use a single-goal policy: reject or queue new goals while one is executing
def handle_goal(self, goal_handle): if self._executing: return GoalResponse.REJECT; return GoalResponse.ACCEPT
-
88% success Implement preemption with threading lock in execute callback
In execute: periodically check if goal_handle.is_cancel_requested or if a new goal has been accepted. Clean up and return CANCELED.
-
85% success Use goal_handle.status to track and manage concurrent goals explicitly
Maintain a list of active goal handles. In handle_goal, cancel previous goals and wait for their execute callbacks to finish.
Dead Ends
Common approaches that don't work:
-
Assume new goals automatically cancel previous goals
90% fail
Unlike ROS1 actionlib, ROS2 action servers do NOT auto-preempt. Multiple goals execute simultaneously unless you explicitly manage goal lifecycle.
-
Cancel the previous goal in handle_goal callback
82% fail
handle_goal is called before the new goal starts executing. Canceling the old goal here creates a race condition if the old execute callback hasn't checked for cancellation yet.