AtsushiSakai/PythonRobotics · error · Exception
Agent index cannot be 0
Error message
Agent index cannot be 0
What it means
Raised by reserve_path when agent_index is 0. Index 0 is the sentinel stored in reservation_matrix to mean 'unreserved', so it cannot be used as a real agent identifier. Agents are expected to be numbered starting from 1.
Source
Thrown at PathPlanning/TimeBasedPathPlanning/GridWithDynamicObstacles.py:299
if zero_mask[-1]: # If the last element is zero, add the last index to end_indices
end_indices = np.append(end_indices, len(vals) - 1)
# Create pairs of (first zero, last zero)
intervals = [Interval(int(start), int(end)) for start, end in zip(start_indices, end_indices)]
# Remove intervals where a cell is only free for one time step. Those intervals not provide enough time to
# move into and out of the cell each take 1 time step, and the cell is considered occupied during
# both the time step when it is entering the cell, and the time step when it is leaving the cell.
intervals = [interval for interval in intervals if interval.start_time != interval.end_time]
return intervals
"""
Reserve an agent's path in the grid. Raises an exception if the agent's index is 0, or if a position is
already reserved by a different agent.
"""
def reserve_path(self, node_path: NodePath, agent_index: int):
if agent_index == 0:
raise Exception("Agent index cannot be 0")
for i, node in enumerate(node_path.path):
reservation_finish_time = node.time + 1
if i < len(node_path.path) - 1:
reservation_finish_time = node_path.path[i + 1].time
self.reserve_position(node.position, agent_index, Interval(node.time, reservation_finish_time))
"""
Reserve a position for the provided agent during the provided time interval.
Raises an exception if the agent's index is 0, or if the position is already reserved by a different agent during the interval.
"""
def reserve_position(self, position: Position, agent_index: int, interval: Interval):
if agent_index == 0:
raise Exception("Agent index cannot be 0")
for t in range(interval.start_time, interval.end_time + 1):
current_reserver = self.reservation_matrix[position.x, position.y, t]View on GitHub (pinned to 1fe4fb980f)
Solutions
- Change the call to use agent_index >= 1 (e.g. use i + 1 in a 0-based loop)
- Audit agent ID assignment so agents are numbered 1..N throughout the codebase
Example fix
# before
for i in range(len(paths)):
grid.reserve_path(paths[i], i)
# after
for i in range(len(paths)):
grid.reserve_path(paths[i], i + 1) Defensive patterns
Strategy: validation
Validate before calling
assert agent_index >= 1, "agent_index must be >= 1 (0 is the unreserved sentinel)"
Type guard
def is_valid_agent_index(idx: int) -> bool:
return isinstance(idx, int) and idx >= 1 Prevention
- Use 1-based agent IDs everywhere; reserve 0 as the 'unreserved' sentinel
- Wrap agent loops: for i in range(1, num_agents + 1)
When it happens
Trigger: Calling grid.reserve_path(node_path, agent_index=0) directly, or via plan(...) passing an agent index of 0 (e.g. iterating agents from a 0-based loop without adding 1).
Common situations: Using a 0-based loop `for i in range(num_agents): plan(path, i)` instead of 1-based indexing; off-by-one errors after refactoring agent IDs; passing a default value of 0 for agent_index.
Related errors
- Agent {agent_index} tried to reserve a position already rese
- Number of obstacles is greater than grid size!
- Path position not found for time {i}.
- No path found
- No path found
AI-assisted analysis of AtsushiSakai/PythonRobotics@1fe4fb980f (2026-08-28).
Data as JSON: /api/errors/f32f14fa39e823f8.
Report an issue: GitHub.