◉CLAUDE LABJP
●2.1.285 — Claude Code 2.1.285 (Sep 29): set CLAUDE_CODE_DISABLE_WEB_FETCH to turn off WebFetch, and run claude --desktop to open the current directory in the desktop app●SONNET5.5 — With 2.1.284, claude-sonnet-5-5 is the default Sonnet on the API: 1M context, $2 / $10 per Mtok, $0.20 cache reads●10/07 — 7 days left until the old spellings of Claude Desktop / Cowork managed-config keys stop being accepted. After the cutoff they fail closed●WINDOWS — Two Windows questions keep coming up in Issues: the desktop app won't relaunch, and it stays on top of every other window. Check for an orphaned process before touching settings●NEW — The stable Claude Code channel still hasn't received two default-model changes●BING — 1,055 Bing sessions in 28 days, up four weeks running. Readers land on billing errors, the Academic plan, Figma MCP and PowerShell●2.1.285 — Claude Code 2.1.285 (Sep 29): set CLAUDE_CODE_DISABLE_WEB_FETCH to turn off WebFetch, and run claude --desktop to open the current directory in the desktop app●SONNET5.5 — With 2.1.284, claude-sonnet-5-5 is the default Sonnet on the API: 1M context, $2 / $10 per Mtok, $0.20 cache reads●10/07 — 7 days left until the old spellings of Claude Desktop / Cowork managed-config keys stop being accepted. After the cutoff they fail closed●WINDOWS — Two Windows questions keep coming up in Issues: the desktop app won't relaunch, and it stays on top of every other window. Check for an orphaned process before touching settings●NEW — The stable Claude Code channel still hasn't received two default-model changes●BING — 1,055 Bing sessions in 28 days, up four weeks running. Readers land on billing errors, the Academic plan, Figma MCP and PowerShell
Articles/Cowork
◈ Cowork/2026-06-27Advanced

Logged as success, but it produced nothing — stopping silent failures in Cowork scheduled tasks with end-of-run assertions

A Cowork scheduled task exits 0, yet not a single artifact was produced. Trusting the exit code alone hides this silent failure. Here is how to turn your definition of done into end-of-run assertions that fail loudly with an evidence log.

cowork15scheduled-task2automation110reliability18

✦ Premium Article

A task you believe is running on schedule keeps logging "SUCCESS" — but you open the output folder and not a single file has appeared since last week. As an indie developer running several sites under Dolice, if you run a handful of unattended Cowork scheduled tasks, you will hit this exact accident at least once. I did, one morning when I sat down to review a batch of logs and realized that a recurring job marked "success" for three days straight had not actually written a single line. My stomach dropped.

The cruel part is that nothing crashed. No exception was raised. The exit code was 0. The scheduler history was green. And yet the deliverable count was zero. This article is about catching that silent success: not by trusting the exit code, but by turning the definition of done itself into assertions that fail loudly.

An exit code does not promise that work happened

We unconsciously read "exit 0" as "it worked." But all an exit code guarantees is that the last command that ran returned 0 — not that the job you actually wanted got done. Those are two completely different propositions.

Silent failure tends to arrive by one of three routes.

RouteWhat happensWhy it stays exit 0
Wrong write targetYou think you generated a file, but it landed in a stale temp path or a directory that doesn't existcat > file itself succeeds. The contents just aren't where you meant
Empty inputYou mistype the path of an input file, and processing proceeds on an empty stringcat wrong-path doesn't error — it returns empty. Downstream "succeeds" on nothing
Commit that never landedAn unset git identity means the commit silently does nothing, and the push goes green with "up to date"There's no diff to push, so the push itself counts as a success

What they share is that every individual command is honestly returning 0. Not one command is lying. And yet the whole thing failed. That is precisely why staring at exit codes from above will never reveal it.

The first time this bit me was a freshly cloned repo where I had forgotten to set the git identity. git commit printed a warning and effectively did nothing; git push came back with "Everything up-to-date." The scheduler history stayed a clean green for three days while the remote gained not one line.

Write your definition of done out loud

The first step toward killing silent failure is not writing code. It is stating, as concrete observable facts, what it means for this job to have succeeded. If that stays vague, you have no way to decide what to assert.

For a recurring job that "reflects generated output into a repo," the definition of done decomposes like this:

  • The output file actually exists and its size exceeds a floor
  • The expected count matches the real file count (for a JA/EN pair, both sides are even)
  • The local commit SHA has changed from its value before the push
  • The remote SHA and the local SHA match

The point is that each of these is a fact you can check from the outside, not a "should be done." Not "I committed" but "the SHA changed." Not "I wrote the file" but "there is a file of at least the floor size at that path." Once you can make that translation, the assertions write themselves.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦Stop trusting exit 0 on automation that quietly produced nothing — you'll be able to detect that silent failure mechanically
✦You'll get a reusable harness that turns your definition of done into end-of-run assertions, writes an evidence log on failure, and exits non-zero
✦You'll learn to separate three nasty states — empty success, partial success, and double production — using idempotency keys and post-run checks
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

Related Articles

◈ Cowork2026-08-23
Not Every Unreachable Connector Means the Same Thing in an Unattended Run
When an unattended task cannot reach a connector, the cause splits into three states: still connecting, unauthenticated, or genuinely absent. Each demands the opposite response. Here is the resolver that tells them apart.
◈ Cowork2026-07-05
When Claude Declines a Request on Safety Grounds, What Should an Unattended Pipeline Return?
A third kind of ending that is neither an error nor a normal completion — a safety decline. Here is how to fold it into a pipeline you run unattended, with a classifier and a review-queue design drawn from indie development.
◈ Cowork2026-05-04
Why Cowork Scheduled Tasks Stop Mid-Run and How to Recover
Diagnose Cowork scheduled task failures using measured exit codes and real error output — why safe.directory delays failure instead of fixing it, how to pick a writable root before cloning, and how to structure logs with reason codes.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links