#17816: Fix media store cleanup ignoring subdirectories (e.g. inbound)
stale
size: S
trusted-contributor
Cluster:
Media File Management Fixes
## Description
The `cleanOldMedia` function only scanned the root media directory, ignoring subdirectories like `inbound/` where Matrix, Signal, and other plugins store received media. This caused the `media/inbound` directory to grow indefinitely.
## Fix
1. Made `cleanOldMedia` recursive.
2. Trigger cleanup on inbound media save (was only on outbound).
3. Added throttling (max once per minute) to prevent excessive filesystem scanning.
## Tests
Added `src/media/cleanup.test.ts` verifying:
- Root files are cleaned up
- Subdirectory files are cleaned up (failed before fix)
## AI Transparency
- **Assisted by**: OpenClaw Agent (Claude 3.5 Sonnet / Opus)
- **Testing level**: Fully tested with new unit tests (`src/media/cleanup.test.ts`)
- **Prompt strategy**: Self-correction loop based on codebase analysis
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Made `cleanOldMedia` recursive to scan subdirectories (like `media/inbound/`) instead of only the root `media/` directory. Added cleanup call in `saveMediaBuffer` so inbound media triggers cleanup. Added throttling (max once per minute) to prevent excessive filesystem scanning.
**Key changes:**
- Recursive directory scanning now cleans files in all subdirectories
- Throttle mechanism prevents cleanup from running more than once per 60 seconds
- `saveMediaBuffer` now triggers cleanup (previously only `saveMediaSource` did)
- Added test coverage for both root and subdirectory cleanup
**Note:** One inline comment about a potential race condition in the throttle mechanism is incorrect - the throttle is safe because the check and update happen synchronously before any `await` points in Node.js's single-threaded event loop.
<h3>Confidence Score: 4/5</h3>
- Safe to merge with one incorrect inline comment that can be disregarded
- The implementation correctly makes cleanup recursive and adds throttling. Tests verify the fix works. One inline comment about a race condition is technically incorrect (the throttle is actually safe in Node's single-threaded model), but the code itself is correct. The fire-and-forget pattern in `saveMediaBuffer` (void + catch) is appropriate.
- No files require special attention - the implementation is sound despite one mistaken inline comment
<sub>Last reviewed commit: 1f63416</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#17630: Fix LINE media temp files accumulating in os.tmpdir
by Clawborn · 2026-02-16
77.9%
#8042: feat(telegram): add media index for reply-to media lookup
by batumilove · 2026-02-03
77.5%
#18811: fix(media): require file extension for ambiguous MEDIA: path detection
by aldoeliacim · 2026-02-17
76.3%
#14794: fix: parse inline MEDIA: tokens in agent replies
by explainanalyze · 2026-02-12
76.2%
#18890: fix(media): parse tool-result MEDIA directives with shared parser
by teededung · 2026-02-17
75.7%
#19868: fix: prevent media token regex from matching markdown bold text
by sanketgautam · 2026-02-18
75.2%
#9817: fix(media): resolve relative paths before reading local files (#8759)
by lailoo · 2026-02-05
74.9%
#17456: fix(test): stabilize media root guard test against tmpdir HOME overlap
by widingmarcus-cyber · 2026-02-15
74.0%
#20022: Fix temp file leak on media download failure
by Clawborn · 2026-02-18
73.9%
#22178: test(web): allow fixture roots in media local file tests
by Kansodata · 2026-02-20
73.5%