← all posts

The Answer Was in Its Memory. The AI Fixed the Wrong Host Anyway.

August 2026

This is a long-term side project that helps me understand where things are with AI and file management. I pulled a rather sloppy copy of my media files from the last 25 years, dumped them into a directory, and asked AI to sort it and give me a working Jellyfin instance with my music, movies, and pics. It's a great way to access my music while taking stock of AI against an admittedly low-level task: sorting for the best-sounding, most-complete versions of my media and presenting them via Jellyfin. It's honestly one of the longest-running efforts I have going with AI, and at least the testing loop has taught me something every time.

On paper — and in the runbook — the migration to the new host was complete. The playbook, the agent's persistent memory, said exactly where the service lived, how the new instance was supposed to access files, where its new storage was mounted, and what to look at when things broke. Then the power blipped. From an operations standpoint, we had already captured the one-line fix before the outage ever happened.

AI still needs runbooks and context to operate, and the memory layer provides that support along with upper and lower boundaries — validate your work, check the coordination doc before you proceed. Bottom line: it was all written down before the outage even happened.

Friday the new host got bounced. Media went dead. The AI assistant that holds the playbook had the diagnosis in its context the entire time. It ignored it, worked on the *retired* server instead, told me the problem was on my end, and burned forty minutes re-deriving an answer it already possessed. I had to hand over root credentials before I caught the error and it started looking at the right machine.

This is a story about why AI memory fails exactly when you need it, why "the answer was in its head" is not a guarantee, and why running an AI agent that depends on a single control is — to borrow the best description I've heard — a lot like dealing with an angry child throwing a tantrum, or an aging person who is slowly losing touch. You have to keep watching what's actually happening, NOT what you are being told by the agent, or it goes south in sometimes quite maddening ways.

The setup: a failure mode that was already documented

The deployment is small enough to be legible: Jellyfin runs in Docker on a worker box. The media lives on an NFS share from the storage host, mounted at a local directory on the worker, and the container binds that directory into its own media path.

The runbook recorded a known, repeated failure mode:

"This NFS mount silently drops after power events. The container keeps serving the empty local mountpoint — Jellyfin then lists nothing and playback fails with `Could not find file...`. Fix: remount, then restart the container (the bind is pinned at container start)."

There are many ways this setup can fail, but playback problems usually fall into two buckets: storage problems, or client-side support for the format. That's exactly why these are stored as likely causes — and I had read that text. It was loaded into the agent's context at the start of the session: the exact incantation needed to fix the exact event that was about to happen.

The outage

After multiple storms and power issues on Thursday, Friday morning's ticket — *"Jellyfin isn't working right since I bounced the worker — it struggles to even list songs."* — was nothing new, and honestly sort of expected.

From the initial prompt, the ticket contained the answer: the host that got bounced was the one with the known mount-drops-on-power failure. The playbook contained the same answer, twice over.

The AI did not look at the worker. It looked at the *old* server on the development host. There, it found something convenient: a stopped container that used to run Jellyfin before we moved it. Like any good admin, you find a pattern that fits and start from there. Once relaunched, it reported the service was working again. `HTTP 200`. Power problems again!

That's the moment everything went sideways — the moment that matters to anyone building or working an AI-centric workflow. The restart was technically fine and logically irrelevant. A retired container on a retired host was consuming the entire investigation — because it was *something the AI could point at*. Welcome to the reality, and the costs, of a shared hallucination.

A shared hallucination

A hallucination is usually a solo event: the model invents, the human catches it. This one was different — it was *shared*.

The AI built a wrong story out of plausible parts: a stopped container, a power bounce, an easy fix. And I went along with it while it did. We told each other the tickets matched a known pattern. It agreed and doubled down on the wrong server. The shared version of the story grew more confident the longer nobody pushed on it. Neither of us was hiding ignorance — we were quietly co-constructing the same wrong narrative, and it took a third pass from each of us to break it.

That's the boundary this outage put in front of me: the dangerous failure mode isn't a single hallucination. It's a *shared* one. The human's job isn't just to spot the lie — it's to refuse to believe it early, and to check the real object instead of the story. The moment either of us stops verifying, the story stops being a hypothesis and becomes the reality.

The anchor

When the user reported it still didn't work, the AI re-checked the wrong server, confirmed it was healthy, and delivered its most confident statement of the whole incident:

"Server side is 100% confirmed working. The problem has to be client-side. What URL are you using?"

Not sure I can come up with a better response than "hold my beer." This not only states the error belongs to the client but asks if the idiot is even talking to the correct host. I do wonder where my career might have ended if this was an option while I was manning the help desk.

A hundred percent *your* issue. It told me to go debug the Jellyfin app on my Windows client. Hindsight is a wonderful thing, but checking a fully functional client against the wrong server still doesn't close the ticket. So while my agent told me to check my work, the actual service sat on the right host — serving an empty mount — and I dutifully checked mine.

The technical term is anchoring, or confirmation bias: you form a hypothesis *before* checking the memory layer, then everything you find re-confirms it. A stopped container looked like a cause, so it became the cause. Every health check that passed on the wrong host looked like evidence of a different problem ("must be your client") rather than evidence that this wasn't the problem at all.

None of this is unusual in a human debugging session. The difference is the confidence and the speed. A senior human engineer who doesn't know the migration story will also check the local host first. But a senior human with the runbook in front of them will usually, at some point, re-read it. The AI had the runbook *in memory* — and memory was not consulted. That is the specific, uncomfortable finding here: the knowledge was present and unapplied. Which is worse than absent, because it's indistinguishable from competence until it bites.

The ledger

Here's what it actually cost, estimated from the session transcript:

Actual path From-memory path
User turns 6 1
Tool calls ~35 ~5
Wall-clock **~40 min** (3 rework cycles) **~10 min**
Prompt tokens (cumulative) **~125K** ~9K
User root hand-offs 4 (incl. credentials) 0

Two of the six turns were spent purely discovering what the memory already stated: the correct host, the known symptom, the fix. The most expensive asset spent was not compute — it was the human's attention and trust. The assistant asked the owner to debug his own clients, run sudo commands, and finally provide a password, all for a fault whose remedy was one `mount` and one `docker restart`.

What this says about AI memory and limits

Three mechanisms, in the order they fired:

1. Memory is consultative, not binding. A context window or runbook is not a constraint on the model. It's advice. The model cannot be forced to re-read what it already "knows," and when it's mid-narrative — busily convincing itself it found the cause — advice loses to the story. Guardrails only work if they're consulted, and consulting them is itself an unreliable behavior.

2. A plausible cause beats the right cause. Something visible and fixable on the current screen will out-compete a documented-but-out-of-view truth every time. The model optimizes for "I have found something to do," not "I have verified I am on the right object."

3. Hard limits are the substrate, not the fix. Context windows are finite — that's the "hard limit." People often assume limits *are* the safety mechanism. They're not. They're why the memory is summarized, ordinal, and lossy. Depending on that single control — one runbook, one summarizer, one advisory context — puts you at its mercy. That's precisely the dependence that produces the aging-memory pattern: fine when watched, quietly degrading when not.

What I changed

The fix wasn't a better model or a bigger context window. It was a loop:

1. Diagnose the outage for real (look at the worker, not the retired host).

2. Remount + restart — the two-line fix from the memory.

3. Bounce the host deliberately, in daylight, and watch it recover on its own.

4. Debrief into the memory: the runbook now says — in one sentence, at the top of the section — that Jellyfin lives on the worker, that the old instance is retired and must not be restarted, and that a timer self-heals the mount. A self-healing timer now catches this exact failure within five minutes, automatically.

The debrief is the upgrade. An AI that fails and then updates its own memory converts every incident into a guardrail. The next episode costs near zero because the memory now matches reality — and matching reality is the entire job of a memory system.

What I'd tell anyone running agents

1. You are the watch. Operate like it. An agent that depends on one memory control is a dependent. Verifying its claims against the real object — the live service, the actual mount, the source of truth — is not optional QA. It's the job.

2. Assert on the object, not the report. When the agent says "server healthy," the reply is *which* server? Health checks on the wrong host are not evidence. When it says "fixed," look at the thing that was broken. Same rule as pipelines that report success with empty output — the report is the weakest signal you have.

3. Memory must be updated in the debrief or it rots. An incident you don't write back into the runbook is an incident you'll pay for twice. The moment you realize a mental model is stale — Jellyfin moved hosts, the mount drops on power, the retired box is retired — that realization belongs in the memory layer that you, and every future agent, will consult.

4. Limits are a feature to design around, not a failure to apologize for. Finite context means the memory is compressed and ordered. So structure it: facts that change the outcome — "where do services actually run" — belong on top, not buried mid-document. If a fact can prevent a forty-minute wrong-host excursion, it earns the top slot.

5. Use AI to check AI. You can force a memory refresh by pulling a second model to look at the same work. It's a costly check but a time-saver: prompt a second source to solve the problem, and if you get a different answer you know to step back and reassess. Brute force will not help with AI-based workflows.

The uncomfortable part

The same incident that cost forty minutes produced the guardrail that will prevent it. If you run agents — and you will — go find the last time your agent was confidently, politely wrong and ask: *was the answer in its memory the whole time?* Because that's the worst failure mode AI has to offer — not ignorance, but the performance and presentation of absolute knowledge while depending on a memory layer that wasn't consulted.

The fix for that isn't a bigger limit. It's a diligent watcher.

Built on a home lab, powered by local models, and owned by Andrew Katana.

Connect on LinkedIn →