Skip to content

CellCollection.select_random_agent() crashes when no agents in cells #2982

@Nithin9585

Description

@Nithin9585

I was building a simple money exchange model where agents on a grid give money to random neighbors. My model kept crashing and I tracked it down to CellCollection.select_random_agent() raising IndexError when there are no agents in the cells.

This happens in sparse grids or when agents die/move, leaving neighborhoods empty. The method tries to call random.choice() on an empty list, which crashes the entire model.

Location: mesa/discrete_space/cell_collection.py, line 111

Expected behavior

The method should either:

  1. Raise a more descriptive error explaining no agents are available, OR
  2. Have a parameter to handle empty cases gracefully

Currently it just crashes with a generic IndexError that doesn't explain the real problem.

To Reproduce

Here's a minimal example showing the crash:

from mesa import Model
from mesa.discrete_space import OrthogonalMooreGrid, CellAgent

class MoneyAgent(CellAgent):
    def __init__(self, model, cell):
        super().__init__(model)
        self.cell = cell
        self.wealth = 100
    
    def step(self):
        if self.wealth > 0:
            # This crashes when neighborhood is empty!
            other = self.cell.neighborhood.select_random_agent()
            other.wealth += 1
            self.wealth -= 1

class MoneyModel(Model):
    def __init__(self, n_agents=5, width=10, height=10):
        super().__init__()
        self.grid = OrthogonalMooreGrid((width, height), random=self.random)
        
        # Sparse grid - most cells empty
        for _ in range(n_agents):
            cell = self.random.choice(list(self.grid.all_cells))
            MoneyAgent(self, cell)
    
    def step(self):
        self.agents.shuffle_do("step")

# Run it
model = MoneyModel()
model.step()  # Crashes!

Error Output:

Traceback (most recent call last):
  File "test_crash_real.py", line 52, in <module>
    model.step()
  File "mesa/model.py", line 136, in _wrapped_step
    self._user_step(*args, **kwargs)
  File "test_crash_real.py", line 41, in step
    self.agents.shuffle_do("step")
  File "mesa/agent.py", line 356, in shuffle_do
    getattr(agent, method)(*args, **kwargs)
  File "test_crash_real.py", line 21, in step
    other = self.cell.neighborhood.select_random_agent()
  File "mesa/discrete_space/cell_collection.py", line 111, in select_random_agent
    return self.random.choice(list(self.agents))
  File "random.py", line 347, in choice
    raise IndexError('Cannot choose from an empty sequence')
IndexError: Cannot choose from an empty sequence

Root Cause

Looking at the code in cell_collection.py:

def select_random_agent(self) -> CellAgent:
    """Select a random agent."""
    return self.random.choice(list(self.agents))  #  Crashes if empty!

When self.agents is empty (no agents in the cells), list(self.agents) returns [], and random.choice([]) raises IndexError.

Proposed Fix

def select_random_agent(self) -> CellAgent:
    """Select a random agent."""
    agents_list = list(self.agents)
    if not agents_list:
        raise ValueError("No agents available in the cell collection")
    return self.random.choice(agents_list)

I'm happy to submit a PR if this looks like a valid issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions