When Anthropic pulled two models overnight — what it takes to keep a proxy honest

On 2026-06-12, two Claude models stopped answering for everyone. The interesting part wasn't the outage. It was what the outage exposed about every tool sitting between you and a model you don't control.

On 2026-06-12, a U.S. government legal directive disabled Claude Fable 5 and Mythos 5 for every Anthropic customer — every plan, every tier, no exceptions (Anthropic's notice). From that moment, api.anthropic.com returned not_found for any request to either model. No subscription, no API key, and no proxy could route around it. The models were simply gone.

For us this was not abstract. We maintain dario, an open-source LLM proxy: you point any Anthropic- or OpenAI-compatible tool at one local endpoint, and dario forwards each request to the model on the subscription you already pay for. It also answers GET /v1/models — it tells clients which models exist. The day before the directive, that list still included claude-fable-5 and its [1m] long-context variant. dario was, through no fault of the directive, now lying to every client that asked it what it could do.

A stale catalog is worse than an empty one

Here's the failure mode. A coding agent asks dario for its model list. dario says claude-fable-5 is available. The agent — reasonably — selects it, perhaps because it was the most capable model the day before. dario faithfully forwards the request to Anthropic. Anthropic returns 404 not_found with a terse upstream body. The agent surfaces that to the user as an opaque error, three layers removed from the actual cause.

The user now debugs the wrong thing. Is it auth? A typo in the model name? A dario bug? A network problem? Every one of those is a plausible read of a bare not_found, and none of them is right. The real answer — "that model was disabled by a legal directive yesterday" — is nowhere in the error.

This is the rule a proxy lives or dies by: a proxy that advertises a capability it cannot deliver is not neutral. It is actively wrong. Forwarding the request "honestly" is the dishonest move, because it launders a known, explainable condition into a mystery. The honest move is to refuse early and say exactly why.

The fix: filter the catalog, refuse at the door

We shipped dario v4.8.71 the next morning. It does two things.

First, suspended model families are dropped from the catalog — both the live list dario autodetects from upstream and the baked fallback it serves when offline. One line at the source of truth:

const bases = dropSuspendedModels(await fetchUpstreamBases(deps));

After that, /v1/models never offers a model that 404s, and the family shortcuts (fable, fable1m) stop resolving. Clients that pick models from the catalog simply never see the dead ones.

Second — for clients that hardcode a model name and never read the catalog — dario rejects suspended models at the door, before it builds the request, leases an account, or forwards anything. The rejection is a clean 404 that actually explains itself and points somewhere useful:

if (requestModel && isSuspendedModel(requestModel)) {
  res.writeHead(404, JSON_HEADERS);
  res.end(JSON.stringify({
    type: 'error',
    error: {
      type: 'not_found_error',
      message: `Model "${requestModel}" is suspended in this dario ` +
        `instance. Use claude-opus-4-8 or claude-sonnet-4-6 instead.`,
    },
  }));
  return;                        // before template build / account lease
}

Matching is by model family, not exact string, so every spelling is caught with no whack-a-mole: fable, fable1m, claude-fable-5, claude-fable-5[1m], and claude:fable all resolve to the same suspended family and get the same answer.

Make the temporary thing reversible without a deploy

This is the part worth keeping. The suspension is a temporary external condition — access may be restored. Hardcoding "fable is dead" into the proxy's logic would mean a code change, a review, a release, and a redeploy on the day it comes back. That's the wrong shape for something you don't control.

So the suspended set is configuration, with a sensible default:

const DEFAULT_SUSPENDED_MODELS = 'fable';

export function suspendedFamilies(): Set<string> {
  const raw = process.env.DARIO_SUSPENDED_MODELS ?? DEFAULT_SUSPENDED_MODELS;
  return new Set(
    raw.split(',').map(s => s.trim()).filter(Boolean)
       .map(s => modelFamily(s) ?? s.toLowerCase()),
  );
}

export function isSuspendedModel(model: string): boolean {
  const fams = suspendedFamilies();
  if (fams.size === 0) return false;        // empty env → nothing suspended
  const fam = modelFamily(model);
  return fam !== null && fams.has(fam);
}

When access is restored, the fix is a single environment variable — DARIO_SUSPENDED_MODELS= (empty) — and a restart. No upgrade, no patch, no waiting on us. The operator who runs the proxy holds the switch, which is exactly who should. Full test suite stayed green at 88/88 through the change.

The real lesson

Models you build on are not a stable foundation. They are a moving target governed by vendor roadmaps, capacity decisions, and — as of this week — legal directives that land overnight with no warning. The gap between "our tool worked yesterday" and "our tool is confusing today" can be opened by a change you had no part in and got no notice of.

Closing that gap is not a feature you ship once. It is a standing job: watch for the change, recognize what it breaks, and respond in a way that tells the truth to the next person down the chain — reversibly, because the change itself might reverse. dario already runs three classes of automated drift detection for exactly this reason. The Fable suspension was a manual catch, shipped in a day, but the instinct is the same one we build everything around.

That instinct — treat someone else's platform as weather, not bedrock, and build the studio to absorb it — is most of what we actually sell.

We build and maintain software on infrastructure that shifts under it — AI integrations, internal tools, the proxies and pipelines in between. If something you depend on keeps changing out from under you, that's the kind of thing we're good at holding steady.

Start a conversation →
← All writing