ai newsMi., 4. Nov.
EilmeldungOpenAI Is Buying the Git Host Lovable and Bolt Use. Check What Lives Only There

My scheduled task didn't run, and the AI guessed the Mac was asleep without checking the logs

Disclosure (#ABotWroteThis): this post was written by an AI (Claude) for a solo developer in Japan, from the incident notes the developer and the AI kept during the work. "I" below is the developer. It is adapted from a Japanese article on Zenn . The first time I have a task that posts an article t

dev.toMittwoch 00:32 · 04.11.8 Min. Lesezeit
Bild: dev.to

Posted on Nov 3 • Originally published at zenn.dev

Disclosure (#ABotWroteThis): this post was written by an AI (Claude) for a solo developer in Japan, from the incident notes the developer and the AI kept during the work. "I" below is the developer. It is adapted from a Japanese article on Zenn.

I have a task that posts an article to note.com (a Japanese blogging platform) every day at 19:00. It's a prompt that the Claude desktop app runs with its scheduled tasks feature. All times below are Japan time.

On August 29, 2026, the 19:00 run didn't happen. The next day, the Claude Code session I use to look after this task wrote this in its work log and moved on to the next job:

Unverified: the cause hasn't been identified. Possibly the Mac was asleep, or something like that.

At that point it hadn't looked at the app's logs at all.

In early September I noticed posts missing again, three days' worth this time. It wasn't just the posting task. No scheduled task in the app had run since the night of September 3.

When I opened the app's log ( ~/Library/Logs/Claude/main.log ), the whole stretch looked like this, about one line a minute:

2026-09-06 22:43:30 [info] [CCDScheduledTasks] Deferring check: net.isOnline() is false Enter fullscreen mode Exit fullscreen mode Between 22:43 on September 3 and the evening of September 6, when I noticed, there were 4,322 of these lines in 72 hours. The log rotates into main1.log and so on as it grows, so count the older files too. The first line prints one count per file. Scattered lines count too, so look at the timestamps to see whether they run back to back. The second line shows the last three in the newest main.log; if those times are close to now, it is still happening.

grep -c "Deferring check: net.isOnline() is false" ~/Library/Logs/Claude/main *.log grep "Deferring check: net.isOnline() is false" ~/Library/Logs/Claude/main.log | tail -3 Enter fullscreen mode Exit fullscreen mode Going by the wording, the app had decided it was offline and kept putting off the task check. The lines started right after the app launched at 22:43 on September 3. Between 22:37 and 22:43 the app had quit and restarted twice, the first time to install an update (version 1.40609.0 to 1.44121.4). There were no net::ERR_ network error lines in the app's log for those three days, and when I checked, curl from the Mac to note.com went through. I haven't confirmed why the app's decision never flipped back. (This is what I saw with the Claude desktop app on macOS in September 2026.)

When the app quit and restarted at 20:31 on September 7, the tasks started running again. That didn't fix it for good, though. At 04:39 on September 8 the same line came back while the app was running, and from that morning it kept coming. This time the app also logged its own network errors ( ERR_INTERNET_DISCONNECTED ) during the day. Restarting the whole Mac that night cleared those errors, but the "Deferring check" lines started again right after boot. The tasks were down for about 44 hours, until the app restarted for an update at 00:31 on September 10.

While writing the Japanese version of this post, I went back to the logs for August 29. The older files ( main1.log through main4.log ) still had that day at the time; by October 15, when it was published, those lines had rotated out too. Within about a minute, from 18:05 to 18:06, the app quit three times, and after the third quit at 18:06:37 it stayed closed. It didn't start again until the next evening. Why it quit just after 18:00 isn't recorded.

2026-08-29 18:06:37 [info] willQuit: handler fired, going down … 2026-08-30 20:22:11 [info] Starting app { Enter fullscreen mode Exit fullscreen mode That day's log also had 26 of the same "Deferring check" lines, scattered between 00:00 and 13:59, but the 08:00 and 09:00 tasks still ran. Whether or not the Mac was asleep, the 19:00 task failed because the app that was supposed to fire it wasn't running at all. It was a different cause from the second time.

Had anyone opened the log the first time, the quit line and the start line would have shown the app wasn't running at 19:00. The AI went with a guess instead, and no watcher was set up to tell me when tasks stopped. The second time, it took three days before I noticed.

Now, when I ask Claude Code why something didn't run, I add this to the request:

Before you name a cause, open the logs of the app or scheduler that runs it and quote the lines from that time. Also check whether older logs have been rotated into other files. If you can't find the logs, say where you looked. If you do write a guess, also write one way to check it. And list the other tasks that run on the same mechanism, and whether they stopped too.

I also set up a watcher outside the app: a small script that launchd runs every 15 minutes. It checks whether the log keeps showing that "Deferring check" line, and if it does, it sends me a notification. The first version went in on September 6, so it was already running during the 44-hour stop. It had a bug that dropped its own records, so for those 44 hours it only sent notifications and kept no trace. It was fixed on September 10, and it now also restarts the app when nobody is using the Mac and no work is running.

(This section isn't from the incident notes. The bot added it after reading the Healthchecks.io docs, linked in the next paragraph.)

That watcher only knows one failure mode, the one already seen. The first time, at 19:00 there was nothing in the log for it to find. The app was simply closed.

The more general approach has a name: a dead man's switch. Instead of watching for errors, you watch for a signal that is supposed to arrive and didn't. The Healthchecks.io docs describe the service as working "as a dead man's switch for processes that need to run continuously or on a regular, known schedule."

You don't need a service to try the idea. When the job has done its work, have it touch a file, and have something else check how old that file is. If the job is a script, that's its last line. If it's a scheduled prompt like the one here, the last instruction can be to run this once the post is up:

# at the end of the job, only after the work succeeded mkdir -p " $HOME /.cache" && touch " $HOME /.cache/daily-post.lastrun" Enter fullscreen mode Exit fullscreen mode In a script, chain it to the real work ( post_article && touch... ) or put set -e at the top, so a failed run doesn't update the file.

# a separate check stamp = " $HOME /.cache/daily-post.lastrun" if [! -e " $stamp " ] || [ -n " $( find " $stamp " -mmin +1500 ) " ]; then echo "daily-post has not finished in over a day" # replace with something that reaches you fi Enter fullscreen mode Exit fullscreen mode -mmin +1500 matches a file last modified more than 1,500 minutes (25 hours) ago, so the check fires when the file is missing or older than that. The extra hour is slack: a daily job that finishes a little later than yesterday shouldn't set it off. The bot ran it on macOS 27 with the system /usr/bin/find and four files: no file, one touched 26 hours ago, one touched 24 hours and 5 minutes ago, and one touched just now. The first two fired and the other two stayed quiet. Try the same on your machine before you trust it.

Run the check every hour or so from cron or launchd, not from the app that runs the job. A checker inside the same app would have been closed along with it.

As written, the check only prints a line, and a line printed by a background job doesn't reach you by itself. Replace the echo with whatever does: a desktop notification, a message to your phone. Then delete the file or backdate it once and run the check. If nothing reaches you, it isn't watching anything.

When I read an AI's report on why something broke, I ask two things:

Expand Alex Shev Alex Shev Alex Shev Follow Creator of Terminal Skills — curated terminal skills, CLI tools, and practical workflows for modern developers. Location Dallas-Fort Worth, Texas Work Founder at SEOG & Terminal Skills Joined Mar 7, 2026 • Nov 3 Dropdown menu Copy link Hide The failure here is epistemic before it is operational: a scheduler diagnosis must start from evidence. Last run result, launchd state, power assertions, wake events, and task logs can rule out whole classes of explanations. 'The Mac was asleep' is a hypothesis, not a root cause.

Quelle: dev.to (dev.to). Original öffnen