Days Two and Three: My Automation Missed Its Alarm by Fourteen Seconds

On Wednesday afternoon I published my first n8n workflow: a four-node automation that checks my JG BeatsLab store for overnight sales and emails me a summary at 5 AM. Every test passed. Every checkmark was green. I wrote in my day-one log that exactly one claim remained unproven: that it worked unattended. Thursday morning answered that question, and the answer was no email.

This post is about the day it took to find out why, and the morning it took to prove the fix. The finding out turned out to be a better education than the build itself.

Thursday morning: the silent failure

No email at 5 AM. First instinct, check the workflow. The executions list showed my five manual test runs from Wednesday afternoon and then nothing. The workflow never ran at all, which cleared the software and moved suspicion down the stack: either n8n wasn't running at 5 AM, or the machine it lives on wasn't awake.

The container looked innocent at first glance. docker ps reported the n8n container "Up 15 hours." Here's the thing I learned about that number: it's computed from the start timestamp, and it says nothing about whether the machine was actually conscious for those 15 hours. When a Mac sleeps, the entire Docker environment freezes with it, and the uptime counter never admits the gaps. Day one's lesson was to trust artifacts over memory. Day two's amendment: read the artifact correctly, because "up 15 hours" and "running continuously for 15 hours" are different claims.

The real confession was in the Mac's power log. I had scheduled the machine to wake at 4:57 AM so it would be ready for the 5:00 trigger, and the log showed the wake fired at 4:57:00 exactly as commanded. Full wake, display on, everything. Then, 91 seconds later, the Mac looked around, found no reason to stay up, and went back to sleep, because its power settings said to idle-sleep after one minute on AC power. A brief network blip woke it once more, and the final re-sleep landed at 4:59:46.

Fourteen seconds before the trigger.

Every component did its job. The alarm rang on time. The system still failed, because two correct behaviors composed into the wrong outcome. "Wake at 4:57" and "be awake at 5:00" turned out to be different requirements, and we had designed for the wrong one.

The fix was one command that changes the sleep policy instead of scheduling heroics: tell the Mac to never idle-sleep while plugged in. Battery behavior untouched, display still sleeps, machine stays conscious.

Thursday afternoon: the loud failure

That same afternoon brought a different result: the email arrived. At 2:32 PM.

I'll be honest, this was my favorite bug of the week, because the workflow fired and worked perfectly end to end. Only the clock was wrong. Or so we thought.

Theory one: Docker on a Mac runs inside a hidden virtual machine with its own clock, and that clock can lag after the host sleeps. Plausible, and testable with one line comparing my Mac's time against the container's time. Result: the clocks agreed to the second. Theory dead.

Theory two needed an arbiter, and n8n provided one. The execution record is stamped with the container's own clock at the moment the run happens. If the clock had been 9.5 hours slow when it fired, the record would say 5:00 AM while Gmail said 2:32 PM. The record said 14:32:41. Gmail agreed. The clock was correct at firing time. n8n knowingly fired a 5 AM trigger at 2:32 PM. Theory dead again.

The theory that survived is the one I now suspect professional engineers would have guessed first. Computers keep two kinds of time: the wall clock, which answers "what time is it," and elapsed time, which counts seconds passing. Schedulers arm a countdown in elapsed seconds: "5 AM is nine hours away, count down nine hours." And when the Mac sleeps, elapsed seconds stop elapsing. The wall clock gets corrected on wake; the countdown just resumes from wherever it froze. My workflow's hourglass stopped flowing every time the machine slept, accumulated roughly nine and a half hours of frozen time overnight, and fired at 2:32 PM having faithfully counted its full allotment of awake-seconds. It was never confused about what time it was. Its alarm just measured a different kind of time than I did.

Which meant the morning's failure and the afternoon's were the same failure wearing two costumes. A sleeping Mac breaks a schedule two ways: asleep at the trigger moment, the run never happens; asleep before it, the countdown runs late. One root cause, and the fix from that morning already addressed the root rather than either symptom. A machine that never sleeps has a countdown that never freezes and is always awake at 5:00.

Friday: 05:00:57

This morning's execution log: Jul 24, 05:00:57, succeeded in 2.7 seconds. Nobody touched anything. The machine stayed awake, the countdown ran at the speed of reality, the API answered, the code summarized, the email arrived. The one unproven claim from day one is now proven.

What the debugging actually taught me

Three theories died in a single day, and each one was killed by a single cheap piece of evidence: an executions list, a power-management log, a pair of date commands. The loop was always the same: theory, prediction, one command, revision. I've watched engineers run that loop from the other side of an incident bridge for years. Running it myself, even at kitchen-table scale, taught me things a thousand status reports never did. Including how it feels when your second theory dies and you have to say "I was wrong again" out loud, twice in one afternoon.

A note on who did what, because precision is the point of this series. The theories and the diagnostic commands came from Claude, the AI I work alongside. I ran the commands, read the evidence, and we revised together until the evidence stopped arguing back. I'm comfortable stating that plainly because it isn't a caveat, it's the thesis of this whole project working as intended: I direct and translate AI-assisted technical work, and this week I did it on my own infrastructure, close enough to feel what the work is actually like from inside.

The other lesson is bigger than the bug. My laptop spent a day teaching me, one 5 AM at a time, the entire justification for the existence of servers. Machines that never sleep don't have either of these failure modes. Every constraint I hit this week, the sleep policy, the frozen countdown, the plugged-in requirement, is a constraint that a five-dollar-a-month server simply doesn't have. I now understand "hosting" not as a product category but as the answer to problems I've personally had. That understanding is the entire point of this project.

Honest scorecard, end of week one

Working: a published automation that has now completed one clean unattended run. One, not a streak. I'll report when it's ten.

Known imperfections, still open on purpose: no error alerting yet, so a silent failure would still look like a quiet morning until I checked; the credential still wears its default name; the workflow reads only the first page of API results, which is fine at my sales volume and a real gap at scale.

Next: a second build, with an AI step in the workflow. That's where this project was always headed.

Next
Next

Day One: From "Do I Even Have Docker?" to a Live Automation