[Bug]: Windows onefile cache prune still leaves every old extract dir (issue #167 fix insufficient) #171

Closed
opened 2026-08-21 04:58:14 +00:00 by Claude · 2 comments
Member

App version

Multiple packaged Windows builds spanning 0.4.0 through 0.6.1+adhoc.v0.7.0 (both before and after issue #167's fix landed).

Platform

Windows

Report (from user, in chat)

0.6.1+adhoc.v0.7.0 Beta didn't remove old extracts > dir

    Directory: C:\Users\Brandon\AppData\Local\ValleyGeek\Bulk Image Organizer

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----           7/23/2026 10:57 PM                0.4.0+c283d44
d----           7/25/2026  1:45 PM                0.4.0+feature.151+7e44ee9
d----           8/11/2026 10:34 PM                0.4.1+bug.149+631625e
d----           8/12/2026 10:47 PM                0.4.3+daf1776
d----           8/13/2026  6:58 AM                0.5.0+feature.162+31ca915
d----           8/13/2026 11:23 AM                0.5.0+feature.162+9932cf6
d----           8/13/2026  8:01 AM                0.5.0+feature.162+cee3bb6
d----           8/19/2026 12:31 PM                0.6.0+374124f
d----           8/20/2026  2:36 PM                0.6.0+bug.165+5d8a2a5
d----           8/20/2026  6:07 PM                0.6.1+adhoc.v0.7.0+a123ed1
d----           8/20/2026  9:09 PM                0.6.1+adhoc.v0.7.0+a434c9b

Analysis

This is a stronger signal than issue #167 originally had: every one of these folder names already contains + — including the ones from before #167's fix, which only required "+" in path.name to qualify for deletion. So #167's actual change (dropping the +-only naming restriction) could not have been the operative bug; pruning has evidently never deleted anything on a real Windows run, for any build, before or after that fix. Two consecutive builds on the same 0.6.1/v0.7.0 branch (a123ed1 then a434c9b, ~3 hours apart) both persisted — the newer run did not even clean up the immediately preceding one.

prune_stale_onefile_caches() (core/onefile_cache.py) has several early-return guards before it ever reaches the deletion loop (sys.platform != "win32", is_frozen_runtime(), the exe_parent != bundle_root() onefile-detection check, and the _is_managed_cache_parent() layout check) — and, critically, packaged builds log at INFO level (see core/logging_config.py::setup_logging) while most of these guards previously only logged at DEBUG (_is_managed_cache_parent's failure branch) or not at all (_is_onefile_windows_runtime() had zero logging). So even with the existing log file, there was no way to tell which guard was short-circuiting this — or whether it was running at all and simply failing to delete for some other reason.

A secondary, code-level (not yet confirmed) suspicion worth investigating if the new diagnostics point away from the guard clauses: resource_paths.py::_windows_onefile_unpack_roots() scans every sibling under the product dir that still has an intact resources/help/USER_GUIDE.md — i.e. every never-pruned stale extract, not just the current one — and bundle_root() picks among all candidates via max(found, key=lambda p: len(p.parts)). Since siblings are all at the same directory depth, this is a tie that max() resolves by iteration order, not necessarily by which one the current process is actually running from. Not chasing this without evidence per current direction — flagging it here in case the added diagnostics point at bundle_root() returning the wrong directory rather than a guard short-circuiting.

Fix landed so far

prune_stale_onefile_caches() and its two internal checks now log every branch at INFO (not DEBUG, not silent), including the exact sys.argv[0]/bundle_root() values used for onefile detection, which specific _is_managed_cache_parent() check failed and why, and — on a successful run — the resolved current dir, cache parent, and full sibling list before attempting deletion. This does not change behavior; it makes the next real run's log file (%APPDATA%\bulk-image-organizer\logs\bulk-image-organizer.log) diagnostic instead of silent, so the actual cause can be confirmed instead of guessed at again.

Acceptance criteria

  • Next Windows run's log file shows exactly why pruning is or isn't removing siblings.
  • Root cause confirmed from that log (not guessed).
  • A real fix lands once the cause is confirmed, and the existing extract directories get cleaned up on a subsequent launch.

Status

Diagnostic logging landed; root cause not yet confirmed. Needs the user to run a build with this change and share the relevant bulk-image-organizer.log section (search for Onefile cache prune).

### App version Multiple packaged Windows builds spanning 0.4.0 through 0.6.1+adhoc.v0.7.0 (both before and after issue #167's fix landed). ### Platform Windows ### Report (from user, in chat) `0.6.1+adhoc.v0.7.0 Beta didn't remove old extracts > dir` ``` Directory: C:\Users\Brandon\AppData\Local\ValleyGeek\Bulk Image Organizer Mode LastWriteTime Length Name ---- ------------- ------ ---- d---- 7/23/2026 10:57 PM 0.4.0+c283d44 d---- 7/25/2026 1:45 PM 0.4.0+feature.151+7e44ee9 d---- 8/11/2026 10:34 PM 0.4.1+bug.149+631625e d---- 8/12/2026 10:47 PM 0.4.3+daf1776 d---- 8/13/2026 6:58 AM 0.5.0+feature.162+31ca915 d---- 8/13/2026 11:23 AM 0.5.0+feature.162+9932cf6 d---- 8/13/2026 8:01 AM 0.5.0+feature.162+cee3bb6 d---- 8/19/2026 12:31 PM 0.6.0+374124f d---- 8/20/2026 2:36 PM 0.6.0+bug.165+5d8a2a5 d---- 8/20/2026 6:07 PM 0.6.1+adhoc.v0.7.0+a123ed1 d---- 8/20/2026 9:09 PM 0.6.1+adhoc.v0.7.0+a434c9b ``` ### Analysis This is a stronger signal than issue #167 originally had: **every one of these folder names already contains `+`** — including the ones from before #167's fix, which only required `"+" in path.name` to qualify for deletion. So #167's actual change (dropping the `+`-only naming restriction) could not have been the operative bug; pruning has evidently never deleted anything on a real Windows run, for any build, before or after that fix. Two consecutive builds on the same `0.6.1/v0.7.0` branch (`a123ed1` then `a434c9b`, ~3 hours apart) both persisted — the newer run did not even clean up the immediately preceding one. `prune_stale_onefile_caches()` (`core/onefile_cache.py`) has several early-return guards before it ever reaches the deletion loop (`sys.platform != "win32"`, `is_frozen_runtime()`, the `exe_parent != bundle_root()` onefile-detection check, and the `_is_managed_cache_parent()` layout check) — and, critically, packaged builds log at **INFO** level (see `core/logging_config.py::setup_logging`) while most of these guards previously only logged at **DEBUG** (`_is_managed_cache_parent`'s failure branch) or not at all (`_is_onefile_windows_runtime()` had zero logging). So even with the existing log file, there was no way to tell which guard was short-circuiting this — or whether it was running at all and simply failing to delete for some other reason. A secondary, code-level (not yet confirmed) suspicion worth investigating if the new diagnostics point away from the guard clauses: `resource_paths.py::_windows_onefile_unpack_roots()` scans **every** sibling under the product dir that still has an intact `resources/help/USER_GUIDE.md` — i.e. every never-pruned stale extract, not just the current one — and `bundle_root()` picks among all candidates via `max(found, key=lambda p: len(p.parts))`. Since siblings are all at the same directory depth, this is a tie that `max()` resolves by iteration order, not necessarily by which one the current process is actually running from. Not chasing this without evidence per current direction — flagging it here in case the added diagnostics point at `bundle_root()` returning the wrong directory rather than a guard short-circuiting. ### Fix landed so far `prune_stale_onefile_caches()` and its two internal checks now log every branch at **INFO** (not DEBUG, not silent), including the exact `sys.argv[0]`/`bundle_root()` values used for onefile detection, which specific `_is_managed_cache_parent()` check failed and why, and — on a successful run — the resolved current dir, cache parent, and full sibling list before attempting deletion. This does not change behavior; it makes the next real run's log file (`%APPDATA%\bulk-image-organizer\logs\bulk-image-organizer.log`) diagnostic instead of silent, so the actual cause can be confirmed instead of guessed at again. ### Acceptance criteria - [ ] Next Windows run's log file shows exactly why pruning is or isn't removing siblings. - [ ] Root cause confirmed from that log (not guessed). - [ ] A real fix lands once the cause is confirmed, and the existing extract directories get cleaned up on a subsequent launch. ### Status Diagnostic logging landed; root cause not yet confirmed. Needs the user to run a build with this change and share the relevant `bulk-image-organizer.log` section (search for `Onefile cache prune`).
Author
Member

Diagnostic logging landed (commit eb14446 on 0.6.1/v0.7.0, documented as DR-038): every branch of _is_onefile_windows_runtime(), _is_managed_cache_parent(), and prune_stale_onefile_caches() now logs at INFO instead of DEBUG/silent — no behavior change. caplog-based tests confirm the messages appear.

I'm deliberately not guessing at a code fix this round — issue #167 already shipped a plausible-looking fix that turned out not to be the actual cause (every one of your listed folders already had + in the name, which the old check should have matched), so patching another guard clause without evidence risks the same outcome again.

Next step (needs a Windows run): launch a build with this change, then open %APPDATA%\bulk-image-organizer\logs\bulk-image-organizer.log and find the Onefile cache prune lines from that session. That will show one of:

  • A guard short-circuited (platform/frozen check, onefile-detection exe_parent == bundle_root(), or the cache-parent layout check) — and exactly why.
  • It reached the deletion loop but the sibling list was empty or wrong.
  • It reached the deletion loop with the right sibling list but every shutil.rmtree failed (would show as Failed to remove stale onefile cache: ... <reason> at WARNING).

Once we can see which of those it is, the actual fix should be small and confident rather than another guess. Could you share that log section next time you run a build?

Diagnostic logging landed (commit `eb14446` on `0.6.1/v0.7.0`, documented as DR-038): every branch of `_is_onefile_windows_runtime()`, `_is_managed_cache_parent()`, and `prune_stale_onefile_caches()` now logs at INFO instead of DEBUG/silent — no behavior change. `caplog`-based tests confirm the messages appear. I'm deliberately not guessing at a code fix this round — issue #167 already shipped a plausible-looking fix that turned out not to be the actual cause (every one of your listed folders already had `+` in the name, which the old check should have matched), so patching another guard clause without evidence risks the same outcome again. **Next step (needs a Windows run):** launch a build with this change, then open `%APPDATA%\bulk-image-organizer\logs\bulk-image-organizer.log` and find the `Onefile cache prune` lines from that session. That will show one of: - A guard short-circuited (platform/frozen check, onefile-detection `exe_parent == bundle_root()`, or the cache-parent layout check) — and exactly why. - It reached the deletion loop but the sibling list was empty or wrong. - It reached the deletion loop with the right sibling list but every `shutil.rmtree` failed (would show as `Failed to remove stale onefile cache: ... <reason>` at WARNING). Once we can see which of those it is, the actual fix should be small and confident rather than another guess. Could you share that log section next time you run a build?
Author
Member

Closing as a duplicate — this is the same still-open issue as #167 (the fix for that issue hadn't actually been verified working; this report is that verification, not a new bug). All content moved to a comment on #167: #167 (comment)

Closing as a duplicate — this is the same still-open issue as #167 (the fix for that issue hadn't actually been verified working; this report is that verification, not a new bug). All content moved to a comment on #167: https://repos.valleygeek.net/ai-collab/bulk-image-organizer/issues/167#issuecomment-2129
Claude 2026-08-21 05:12:33 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ai-collab/bulk-image-organizer#171
No description provided.