Skip to content

fix: prevent time rewind in _advance_time by adding early return#3329

Merged
quaquel merged 11 commits intomesa:mainfrom
Krishsharma179:fix-time-rewind
Feb 17, 2026
Merged

fix: prevent time rewind in _advance_time by adding early return#3329
quaquel merged 11 commits intomesa:mainfrom
Krishsharma179:fix-time-rewind

Conversation

@Krishsharma179
Copy link
Copy Markdown
Contributor

Summary

Fixes critical bug where model.run_until() incorrectly rewinds simulation time when target time is less than current time. Time must be monotonic in simulations (never decrease) to maintain causality and data integrity.

Bug / Issue

Related Issue: #3327
Context: When calling model.run_until(target) where target < model.time, the method overwrites model.time = target, causing time to jump backward.
Expected: Time should remain unchanged (no-op) when target is in the past.
Actual: Time rewinds (e.g., run_for(10) → time=10, then run_until(5.0) → time=5.0 (wrong)).

Implementation

Modified mesa/model.py in _advance_time() method:

def _advance_time(self, until: float) -> None:
    """Advance time to the given point, processing events along the way."""
    # PREVENT TIME REWIND: exit immediately if target is in the past
    if until <= self.time:  # ← ADDED THIS GUARD CLAUSE
        return
    
    # ... (existing event processing logic) ...
    self.time = until

Testing

m = Model()
m.time = 10.0
m._advance_time(5.0)  # Attempt to rewind
assert m.time == 10.0  # ✅ PASS: Time unchanged
m._advance_time(15.0)  # Forward advancement
assert m.time == 15.0  # ✅ PASS: Still works

output:
✅ Time remains 10.0 after run_until(5.0) (no rewind)
✅ Forward advancement to 15.0 works correctly
✅ All existing Mesa tests pass (verified locally)
If you're fixing the visualisation, add before/after screenshots. -->

Additional Notes

Minimal change: Only 2 lines added, no logic modifications elsewhere
Critical for: Time-series data integrity, agent state consistency, reproducibility
No side effects: Guard clause exits early before any event processing
Standards compliance: Aligns with universal simulation principle: "Time never decreases"
Future-proof: Prevents subtle bugs in complex models using event scheduling

@github-actions
Copy link
Copy Markdown

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small 🟢 -3.9% [-4.5%, -3.2%] 🔵 -1.8% [-2.1%, -1.5%]
BoltzmannWealth large 🔵 -1.7% [-2.7%, -0.9%] 🔵 -2.5% [-4.8%, -0.5%]
Schelling small 🔵 +0.9% [+0.3%, +1.5%] 🔵 +1.3% [+1.0%, +1.7%]
Schelling large 🔵 -0.8% [-1.6%, +0.1%] 🔵 -2.5% [-4.2%, -0.8%]
WolfSheep small 🔵 -0.3% [-0.9%, +0.2%] 🔵 -0.8% [-1.0%, -0.5%]
WolfSheep large 🔵 -3.6% [-4.4%, -2.7%] 🟢 -5.0% [-5.8%, -4.0%]
BoidFlockers small 🔵 -0.2% [-0.5%, +0.2%] 🔵 -1.8% [-2.0%, -1.7%]
BoidFlockers large 🔵 -0.8% [-1.3%, -0.4%] 🔵 -2.2% [-2.6%, -1.9%]

Copy link
Copy Markdown
Member

@EwoutH EwoutH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Code itself looks good. We should add a (small) testcase for this.

@quaquel maybe we also want to add a warning here?

@EwoutH EwoutH added the bug Release notes label label Feb 17, 2026
@quaquel
Copy link
Copy Markdown
Member

quaquel commented Feb 17, 2026

  1. I would move the check to run_until.
  2. Adding a warning would be a good idea
  3. Yes, we need an extra test. This is trivial, see my issue where I point to the test that needs to be updated.

Note that I am working on a bigger PR with a larger set of bug fixes and other improvements for model.time. I am including this one in that as well. But I am happy to merge this one if it is in line with my suggestions.

@Krishsharma179
Copy link
Copy Markdown
Contributor Author

Thanks for the review @EwoutH and @quaquel !

I'll implement both suggestions:

  1. Add a warning when time rewind is attempted
  2. Add a test case to prevent regression

I'll push the updates to this branch today.

@Krishsharma179
Copy link
Copy Markdown
Contributor Author

hey @EwoutH and @quaquel please check the implementation I've made according to your suggestions

Copy link
Copy Markdown
Member

@quaquel quaquel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 minor change still open. I will merge afterwards

@quaquel quaquel added the backport-candidate PRs we might want to backport to an earlier branch label Feb 17, 2026
@quaquel quaquel merged commit bd22e4a into mesa:main Feb 17, 2026
11 checks passed
@Krishsharma179 Krishsharma179 deleted the fix-time-rewind branch February 18, 2026 01:37
Krishsharma179 added a commit to Krishsharma179/mesa that referenced this pull request Feb 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-candidate PRs we might want to backport to an earlier branch bug Release notes label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants