{"record":{"id":"eb88ff8a258a73ce","repo":"AtsushiSakai/PythonRobotics","slug":"agent-agent-index-tried-to-reserve-a-position-al","errorCode":null,"errorMessage":"Agent {agent_index} tried to reserve a position already reserved by another agent: {position} at time {t}, reserved by {current_reserver}","messagePattern":"Agent (.+?) tried to reserve a position already reserved by another agent: (.+?) at time (.+?), reserved by (.+?)","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"PathPlanning/TimeBasedPathPlanning/GridWithDynamicObstacles.py","lineNumber":319,"sourceCode":"        for i, node in enumerate(node_path.path):\n            reservation_finish_time = node.time + 1\n            if i < len(node_path.path) - 1:\n                reservation_finish_time = node_path.path[i + 1].time\n\n            self.reserve_position(node.position, agent_index, Interval(node.time, reservation_finish_time))\n\n    \"\"\"\n    Reserve a position for the provided agent during the provided time interval.\n    Raises an exception if the agent's index is 0, or if the position is already reserved by a different agent during the interval.\n    \"\"\"\n    def reserve_position(self, position: Position, agent_index: int, interval: Interval):\n        if agent_index == 0:\n            raise Exception(\"Agent index cannot be 0\")\n\n        for t in range(interval.start_time, interval.end_time + 1):\n            current_reserver = self.reservation_matrix[position.x, position.y, t]\n            if current_reserver not in [0, agent_index]:\n                raise Exception(\n                    f\"Agent {agent_index} tried to reserve a position already reserved by another agent: {position} at time {t}, reserved by {current_reserver}\"\n                )\n            self.reservation_matrix[position.x, position.y, t] = agent_index\n\n    \"\"\"\n    Clears the initial reservation for an agent by clearing reservations at its start position with its index for\n    from time 0 to the time limit.\n    \"\"\"\n    def clear_initial_reservation(self, position: Position, agent_index: int):\n        for t in range(self.time_limit):\n            if self.reservation_matrix[position.x, position.y, t] == agent_index:\n                self.reservation_matrix[position.x, position.y, t] = 0\n\nshow_animation = True\n\ndef main():\n    grid = Grid(\n        np.array([11, 11]),","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/AtsushiSakai/PythonRobotics/blob/1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d/PathPlanning/TimeBasedPathPlanning/GridWithDynamicObstacles.py#L301-L337","documentation":"Raised by reserve_position when the target cell in reservation_matrix already holds a different agent's index during any timestep in the requested interval. This is a collision/conflict detection mechanism for multi-agent space-time reservation.","triggerScenarios":"Calling reserve_position/reserve_path for a path that passes through (or waits on) a cell-time already reserved by another agent; typically when planning paths sequentially without accounting for previously reserved intervals.","commonSituations":"Planning multi-agent paths where a later agent's plan crosses an earlier agent's reserved trajectory; wait-in-place actions that collide with another agent's reservation; replanning without clearing stale reservations.","solutions":["Re-plan the conflicting agent with the reservation matrix as a constraint (treat reserved cells as blocked)","Adjust the path or departure time so it avoids the conflicting (position, time) pair named in the message","Clear stale reservations for an agent before replanning its path (clear_initial_reservation / reset matrix)"],"exampleFix":"# before\npath = planner.plan(start, goal)\ngrid.reserve_path(path, agent_index)  # may collide\n\n# after\n# use a planner that respects reservations (SpaceTimeAStar/SafeInterval with the grid), then reserve\npath = planner.plan(start, goal)\ngrid.reserve_path(path, agent_index)  # planner already avoided reserved cells","handlingStrategy":"try-catch","validationCode":"def is_free(grid, position, interval, agent_index) -> bool:\n    return all(\n        grid.reservation_matrix[position.x, position.y, t] in (0, agent_index)\n        for t in range(interval.start_time, interval.end_time + 1)\n    )","typeGuard":null,"tryCatchPattern":"try:\n    grid.reserve_path(path, agent_index)\nexcept Exception as e:\n    if 'already reserved by another agent' in str(e):\n        # replan with reservations as constraints, then retry\n        path = planner.plan(grid, start, goal)\n        grid.reserve_path(path, agent_index)\n    else:\n        raise","preventionTips":["Always plan with a reservation-aware planner (SpaceTimeAStar/SafeInterval on the same grid) before reserving","Reserve paths sequentially and replan on conflict rather than precomputing all paths independently"],"tags":["path-planning","multi-agent","collision","reservation","conflict"],"backgroundTag":"multi-agent-path-conflict","analyzedSha":"1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d","analyzedAt":"2026-08-28T13:23:33.733Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}