[Bug]: Monitor with override_existing=False writes no header when the file is new

Author: yurekamiCreated Sep 4, 2026Updated Sep 4, 2026

Bug

Monitor(..., override_existing=False) with a filename that does not exist yet creates the file in append mode without writing the #{json header} line or the CSV column names. ResultsWriter.__init__ only writes the header when override_existing=True, so the first run of a script that uses the append mode (the use case override_existing was added for in #1037 / #1035) produces a monitor.csv that load_results() and results_plotter cannot read.

To Reproduce

python
import gymnasium as gym
from stable_baselines3.common.monitor import Monitor, load_results

env = Monitor(gym.make("CartPole-v1"), "logs/run.monitor.csv", override_existing=False)  # path does not exist yet
obs, _ = env.reset()
done = False
while not done:
    obs, r, terminated, truncated, _ = env.step(env.action_space.sample())
    done = terminated or truncated
env.close()

print(open("logs/run.monitor.csv").read())   # first line is a data row, no "#{...}" header, no "r,l,t" line
load_results("logs")                         # AssertionError

Relevant log output / Error message

AssertionError  (raised by load_results: the first line is a data row, not "#{...}")

System Info

  • stable-baselines3 master (de477a1's parent), Python 3.11, Windows 11; also reproduces on Linux since the logic is platform independent.

Checklist

  • My issue does not relate to a custom gym environment.
  • I have checked that there is no similar issue in the repo
  • I have read the documentation
  • I have provided a minimal and working example to reproduce the bug
  • I've used the markdown code blocks for both code and stack traces.

Source: DLR-RM/stable-baselines3