opencode icon indicating copy to clipboard operation
opencode copied to clipboard

fix(log): await cleanup and sort files before deletion

Open djnawara opened this issue 3 weeks ago • 3 comments

Summary

  • Await cleanup() in init() to prevent race condition where cleanup could run concurrently with file creation
  • Sort files before slicing to ensure oldest files are deleted, not arbitrary files based on filesystem order

Problem

Log files were being deleted immediately after creation due to two issues:

  1. cleanup() was called fire-and-forget (not awaited), creating a race condition
  2. Bun.Glob.scan() returns files in arbitrary filesystem order, so slice(0, -10) was deleting random files instead of the oldest ones

Fix

  • Added await before cleanup() call
  • Added .sort() before .slice(0, -10) to ensure lexicographic order (which matches chronological order for the YYYY-MM-DDTHHMMSS.log filename format)

Tests

Added 8 tests covering:

  • File creation (timestamp name, dev.log)
  • Cleanup threshold behavior (5, 10, 11 files)
  • Oldest file deletion
  • Newest 10 files preserved
  • dev.log excluded from cleanup (doesn't match glob)
  • New log file created after cleanup runs

djnawara avatar Jan 07 '26 19:01 djnawara

The following comment was made by an LLM, it may be inaccurate:

Based on my search, I found one potentially related PR:

Related PR:

  • #6641 - fix: prevent log file deletion when using --log-level DEBUG

This PR also addresses log file deletion issues, which may be related to the race condition and deletion logic being fixed in PR #7245. You may want to verify if this PR is addressing a symptom of the same underlying bugs (race condition and improper file sorting) that PR #7245 fixes.

No other duplicate PRs found addressing the same cleanup/sort/race condition issues.

github-actions[bot] avatar Jan 07 '26 19:01 github-actions[bot]

FYI spent some time on this today because I'm working on a plugin and saw that my log was deleted while i still had the handle open. I pinged #6641 because this is very closely related.

djnawara avatar Jan 07 '26 19:01 djnawara

Also, I used this script to prove out the race. I would just boot the TUI via this script, and then exit immediately. After a few tries, it shows up.

test-opencode-race.sh

Also note that you sometimes get 2 log files, because init() is called in the main process and then also for a worker sub-process, and there is no coordination on name/timestamp. The filename is based on the current time; the race is something like 180 ms on my machine i think, and can cross the boundary and result in 1 log file for each call.

djnawara avatar Jan 07 '26 19:01 djnawara