Flush cache generates a "Directory not empty" error

I have a project where I create/delete pages via a plugin which is ran via a cron job.

Sometimes I notice that the importer did not ran succesfully, and usually find something like this in the log:

[2025-12-09 1:11:48.792799] [error] Whoops\Exception\ErrorException: rmdir(/data/sites/my-website.tld/prd/data/runtime/cache/my-website.tld/pages): Directory not empty in /data/sites/my-website.tld/prd/kirby/src/Filesystem/Dir.php:587
Stack trace:
#0 [internal function]: Whoops\Run->handleError()
#1 /data/sites/my-website.tld/prd/kirby/src/Filesystem/Dir.php(587): rmdir()
#2 /data/sites/my-website.tld/prd/kirby/src/Cache/FileCache.php(219): Kirby\Filesystem\Dir::remove()
#3 /data/sites/my-website.tld/prd/kirby/src/Cms/FileActions.php(184): Kirby\Cache\FileCache->flush()
#4 /data/sites/my-website.tld/prd/kirby/src/Cms/FileActions.php(313): Kirby\Cms\File->commit()
#5 /data/sites/my-website.tld/prd/kirby/src/Cms/PageActions.php(646): Kirby\Cms\File->delete()
#6 /data/sites/my-website.tld/prd/kirby/src/Cms/PageActions.php(413): Kirby\Cms\Page->Kirby\Cms\{closure}()
#7 /data/sites/my-website.tld/prd/kirby/src/Cms/PageActions.php(640): Kirby\Cms\Page->commit()
#8 /data/sites/my-website.tld/prd/site/plugins/my-plugin/classes/Importer/Importer.php(109): Kirby\Cms\Page->delete()
#9 /data/sites/my-website.tld/prd/site/plugins/my-plugin/classes/Importer/Importer.php(78): bvpdutte\my-plugin\Importer\Importer->createPage()
#10 /data/sites/my-website.tld/prd/scripts/importer.php(514): bvpdutte\Importer\Importer->import()
#11 {main}

I believe `Page→delete()` flushes the page cache. I think there’s some kind of a race condition going on (I cannot replicate it); I assume when the cache is being deleted, the low-level `Dir::remove()` function first empties the folder, by manually looping over each item & removing it.

When there’s lots of items in that folder, I assume this step can take a while, and if in the mean time another item is being written to that pages cache folder, it won’t be empty anymore and given error will be thrown.

Is my assumption correct? Is this intended? How do I work around this?

Thx!

Hey Bart,

just a quick update from us. We’ve been looking into it and it’s indeed a race condition and a problem with the way Dir::remove() handles warnings. We are currently trying to find a solution to improve this.

Thanks so much for getting back @bastianallgeier .

Looking back I probably better issued this on github. I am confident you guys will come up with an improvement. I’m already looking forward for this :folded_hands: