iCloud Silently Evicted 69 Article Files and Killed 4 Days of Publishing: EDEADLK and a read_text_resilient Design

2026年8月21日1 次浏览来源:Dev.to阅读原文

Every one of my publishing lanes went dark for four days, and every script involved exited with status

0.

Nothing had crashed.

The files themselves had quietly stopped existing on disk — macOS had uploaded them to iCloud and deleted the local copies to "optimize storage." Why This Matters What it means for automation to depend on its environment When you run 160+ launchd jobs around the clock, the execution environment itself becomes a failure source before your script logic does.

Ports get exhausted, processes orphan and pile up, memory never frees — I wrote about that class of resource leak last time.

This is a completely different kind of total failure that happened the very next day.

The files had become fatal to read.

Not a bug in my code.

Not a filesystem bug.

An unintended side effect of a mechanism macOS runs under the name "optimization." What optimize-storage actually does macOS's "Optimize Storage" (System Settings → General → Storage → Optimize Storage), on a machine with iCloud Drive enabled, uploads files under Desktop and Documents to iCloud and deletes the local copies when free disk space gets tight.

In Finder they still look like normal icons, but there is no local data — they are in a "dataless" state.

Click one and it downloads automatically.

For a human user, that's an acceptable tradeoff.

The problem is automation scripts. 's , , , , — all of them die instantly on a dataless file with .

The name "Resource deadlock" makes you suspect a deadlock, but this is a POSIX errno code that macOS repurposes to mean "waiting for a file download." No lock is contended.

No thread is stuck.

The mere fact that "the data isn't local" surfaces to the process as a fatal error code.

You can also get EAGAIN (resource temporarily unavailable).

That one shows up as a race right after a download starts.

The actual damage: four days of zero posts On August 6, 2026, note's automated publishing stopped across every lane.

The error log was a wall of EDEADLK.

Digging in, 69 article files under had gone dataless.

Disk usage had hit 98% (25GB free), and iCloud had silently evicted the data at that moment.

That's exactly where the note lane was reading from.

It couldn't read, so it couldn't post.

It couldn't post, so there was no revenue.

Starting August 3, four days of zero posts.

The lane producing most of my revenue had stopped in a form that showed neither errors nor "failure" alerts at a glance — that's what stung most.

The script returns .

It's treated as "no articles found, so nothing to do," so the liveness check passes as "success." Silent failures are the ones you discover last.

The previous day's (August 5) incident was "resource leak: memory and orphaned processes." A different kind of total failure arrived one day later, and both present as "all lanes stopped." The root causes differ; the surface is identical.

Without a triage pattern, you burn an hour every time.

The Vault had the same problem Something else I noticed the same day while working: the Markdown files under my Obsidian Vault () were repeatedly going dataless too. and my learning notes get re-evicted as long as disk pressure continues, no matter how many times I materialize them with .

This isn't a Desktop-only problem.

Every folder synced to iCloud Drive is in scope.

Documents included.

As long as your automation's read/write targets live there, the same thing happens every time the disk fills up.

The Overall Picture The permanent fix has two pillars.

Fix A: Move automation's read/write targets out of Desktop/Documents This cuts the problem off at the root.

I moved the actual data of 796 article files from to and left a symlink at the original path.

Even if a launchd job fires mid-migration, it can still read through the symlink, so the job doesn't break.

Updating the path constants is a one-line replacement per script.

This time I just replaced with across 9 files total (JavaScript, MJS, Shell) and confirmed zero hits with a residual check () — commit .

This

分享
Baike.dev

baike.dev helps you discover great languages, frameworks, databases, DevOps and cloud-native tools.

Quick links

About

Contribute

Found a great developer tool? Share it with the community.

Submit a tool
© 2026 baike.dev Developer EncyclopediaUpdated daily · Discover great developer tools