◉CLAUDE LABJP
●2.1.292 — Claude Code 2.1.292 (Oct 6) fixes cloud sessions dropping answers to permission prompts and the last messages of a session being lost on quit●MODELS API — The Models API now reports in capabilities whether a model accepts thinking turned off (Oct)●11/30 — 54 days until Sonnet 4.5 retires on the Claude API. Move to Sonnet 5.5, and check your thinking settings and tool_choice first●MODS — A Zenn post walks through installing Claude Code Mods safely. The real question is what to check before you install, and how to back out●NEW — When Pro looks unpaid, the screens to check depend on whether you bought on the web or in the store. I sorted that out step by step●THINKING — Sonnet 5.5 thinking blocks only work in the account that produced them. Sent from another account, they are silently dropped●2.1.292 — Claude Code 2.1.292 (Oct 6) fixes cloud sessions dropping answers to permission prompts and the last messages of a session being lost on quit●MODELS API — The Models API now reports in capabilities whether a model accepts thinking turned off (Oct)●11/30 — 54 days until Sonnet 4.5 retires on the Claude API. Move to Sonnet 5.5, and check your thinking settings and tool_choice first●MODS — A Zenn post walks through installing Claude Code Mods safely. The real question is what to check before you install, and how to back out●NEW — When Pro looks unpaid, the screens to check depend on whether you bought on the web or in the store. I sorted that out step by step●THINKING — Sonnet 5.5 thinking blocks only work in the account that produced them. Sent from another account, they are silently dropped
Articles/Cowork
◈ Cowork/2026-08-23Advanced

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.

cowork15mcp20automation109scheduled-tasks5reliability18

✦ Premium Article

One line was all the morning log had for me.

"No matching capability was found."

The task had run cleanly the day before. When I retraced the same steps by hand, the connector answered immediately. Re-running the task succeeded. The next morning, the same single line came back. After a few rounds of this, the answer finally landed: the task had not been lying. At the instant it looked, that connector genuinely did not exist.

As an indie developer running more and more of my operations on scheduled tasks, I keep tripping over this family of failures — the ones whose outcome depends on what time you looked. What makes them nasty is that they all look identical from the outside. Faced with a connector that will not answer, a machine can only say "missing." But missing turned out to have more than one meaning.

An unreachable connector shows three different situations with the same face

Watching a real runtime bring its connectors up, I counted at least three distinct reasons a tool can fail to appear.

The first is that startup has not finished. A connection is being negotiated in the background, and the tool will show up in the inventory seconds later. Declaring it missing is not wrong so much as premature.

The second is that authentication has lapsed. The token expired, or the initial grant was never completed. The server itself is alive and its name is visible, but every call bounces. In an unattended context this one is decisive: the authorization handshake needs a human at a browser, so no amount of waiting will fix it.

The third is that the connector is simply not connected — removed from configuration, or no longer served in this environment. Waiting will not help here either, but the correct response differs from the second case: you look for an alternate path, or you drop the capability entirely.

One symptom, three correct behaviors. Collapse them into one and you end up giving up when you should have waited, and waiting when you should have given up.

StateWhat it really isDoes time fix it?Default behavior
connectingHandshake in progressUsually, within secondsWait, within a budget
unauthenticatedGrant missing or expiredNo — needs a humanHand back immediately
absentNot connected or not servedNoFall back, or drop the step

The smallest resolver that tells the three apart

You need surprisingly little to classify. The tools currently usable, the servers still handshaking, and the servers waiting on authorization. Keep it a pure function and you can test it later.

// resolver.mjs — classify why a connector is unreachable
export const READY = "ready";
export const CONNECTING = "connecting";
export const UNAUTHENTICATED = "unauthenticated";
export const ABSENT = "absent";
 
// mcp__google-drive__search → "google-drive"
// Built-in tools (Bash and friends) have no server, so "builtin"
export function serverOf(toolName) {
  const m = /^mcp__([^_]+(?:_[^_]+)*?)__/.exec(toolName);
  return m ? m[1] : "builtin";
}
 
export function classify(toolName, snapshot) {
  const { readyTools, pendingServers, unauthenticatedServers } = snapshot;
 
  // 1. If it works, stop asking questions
  if (readyTools.includes(toolName)) return READY;
 
  const server = serverOf(toolName);
 
  // 2. Check auth FIRST. Check it later and you will misread
  //    a permanent block as "it will show up eventually"
  if (unauthenticatedServers.includes(server)) return UNAUTHENTICATED;
 
  // 3. Still handshaking? Then do not conclude anything yet
  if (pendingServers.includes(server)) return CONNECTING;
 
  // 4. None of the above: it does not exist for this run
  return ABSENT;
}

The order of those checks carries weight. Authentication is tested before the pending check because a server awaiting authorization frequently appears in the pending list at the same time. Flip the order and you have written code that waits forever on something that can never resolve. That single line ordering is what produced the timing difference below.

✦

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
✦You will be able to split every unreachable connector into still-connecting, unauthenticated, or absent, and route each one to a different response automatically
✦You will be able to prevent the failure mode where an unattended run reports a capability as missing and quietly accomplishes nothing
✦You will be able to move capability checks from the start of a run to the moment of use, so your tasks stop depending on startup order
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-09-08
Until I planted a failing sample, my unattended checks had never once failed
A check running on an unattended schedule lost its exit code to a single pipe added for readable logs. I measured where the status disappears and built a small harness that checks the checker.
◈ 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.
◈ Cowork2026-09-16
The scheduled task that only ran on days my desk was awake
Cowork scheduled tasks run remotely by default, but the moment one needs a local file or app, it runs only on your machine. Here is how the last field in the setup dialog decides that, and the three questions I now answer before creating a task.
📚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