I gave my coding agent persistent memory in March. By the end of the week it was telling me, with total confidence, that I preferred Poetry for dependency management, that our staging database lived in us-east-1, and that I had already approved a migration plan I had explicitly rejected two days earlier.
All three were wrong. I use uv. Staging moved to ap-northeast-1 back in February. And I never approved that plan.
The annoying part is that none of these were hallucinations in the usual sense. The agent wasn't making things up on the spot. It was faithfully recalling facts it had written down about me at some point and never corrected. The memory worked exactly as designed. That was the problem.
The pitch everyone believes
The standard story about agent memory goes like this. Every session starts with a blank context window. The agent forgets you the moment the conversation ends. So you give it persistent memory: a place to write down your preferences, your project state, the decisions you've made. Next session, it reads those notes first and picks up where it left off.
Anthropic shipped exactly this for all Claude users in March 2026. Claude now scans your history, synthesizes a summary of who you are and what you're working on, and refreshes it roughly every 24 hours. Letta (the framework formerly known as MemGPT) goes further: the agent edits its own memory blocks through tool calls, deciding what's worth keeping.
The selling point is continuity. No more re-explaining your stack every morning. And for the first few days, it genuinely felt like working with someone who remembered me.
Then it started remembering things that were no longer true.
Stale memory is worse than no memory
Here's the uncomfortable asymmetry. An agent with no memory asks you the same question every day. That's annoying, but it's honest. You answer, it acts, nothing rots.
An agent with persistent memory answers the question itself, using a fact it learned three weeks ago. If that fact has changed, you don't get a question. You get a confident wrong action. And because the answer sounds informed, you're less likely to catch it.
My us-east-1 bug is the clearest example. The agent had recorded our staging region back when it was true. We migrated. Nobody told the memory. So for a week the agent kept generating deploy commands pointed at a region with nothing in it, and every command looked perfectly reasonable because the region string was a real region we had genuinely used.
This is the part the memory pitch skips. "Remembering" and "remembering correctly" are different features, and persistence only gives you the first one for free.
The three ways memory goes bad
After staring at my agent's memory file for an embarrassingly long evening, I sorted the failures into three buckets. They're not exotic. They show up the moment a memory system runs longer than a few days.
Stale facts. Something that was true when it was written and isn't anymore. Regions, versions, deadlines, who owns which service. The world moves; the note doesn't. This was most of my pain.
Poisoned facts. A wrong fact gets written once and then quoted forever. The "I approved the migration" entry came from a single ambiguous message where I said "yeah that approach makes sense" about the general shape of a plan. The agent compressed that into approval, wrote it down, and from then on treated it as settled history. No amount of arguing in later sessions dislodged it, because it kept reloading the poisoned note at the start of each one.
Over-confident summaries. The Poetry thing was this. I'd mentioned Poetry once, months ago, in the context of a different repo. The summarization pass that builds the daily profile flattened "used Poetry on one old project" into "prefers Poetry." Summaries are lossy by design, and the loss tends to drift toward overconfident generalizations.
The first one is a freshness problem. The second is an integrity problem. The third is a compression problem. Lumping them together as "the agent got confused" is exactly why they're hard to fix.
Why self-editing memory doesn't save you
The obvious response is: let the agent manage its own memory. It edits, it prunes, it corrects. Letta is built on this idea, and it's a genuinely good idea.
But teams moving Letta from prototype to production keep hitting the same wall, and I hit it too: self-editing memory is unpredictable. The agent decides what to keep based on the same flawed judgment that wrote the bad fact in the first place. When I corrected the region in a session, the agent sometimes updated the memory block, sometimes wrote a second entry that contradicted the first, and once helpfully "consolidated" both into a summary that kept the wrong one. Letta even shipped a Recovery-Bench benchmark in 2026 specifically to measure how well agents climb out of corrupted states, which tells you the industry knows this is real.
The deeper issue: an agent editing its own memory has no external source of truth to check against. It's grading its own homework. If it believed us-east-1 yesterday, "us-east-1" looks consistent with everything it knows today.
I learned this lesson once before, the hard way, with a junior engineer I onboarded years ago. Brilliant, fast, and absolutely certain about a deployment process he'd learned on his first day. The process had changed in month two. He kept doing it the old way for weeks, confidently, because nobody handed him a reason to doubt his own notes. Persistent memory gave my agent the exact same failure mode, minus the part where a human eventually overhears the mistake at lunch.
What actually started working
I'm not going to pretend I solved this. But three changes cut the wrong-fact rate to something I can live with.
Timestamp everything, and decay it. Every memory entry now carries when it was written. Facts about volatile things (regions, versions, deadlines) get treated as suspect after a set window and re-confirmed rather than trusted. A region string from three weeks ago isn't a fact; it's a hypothesis with an expiry date.
Separate "observed" from "inferred." The Poetry disaster came from the agent storing a generalization as if it were a stated preference. Now there's a hard line: things I literally said go in one bucket, things the agent concluded go in another, and the inferred bucket needs more evidence before it gets to drive an action. Augment's framing stuck with me here: memory should guide decisions, but never be treated as infallible truth.
Make corrections destructive. When I correct a fact, the old entry doesn't get a polite contradicting neighbor. It gets overwritten and logged. The audit log matters more than I expected. The first time the agent confidently cited a fact I didn't recognize, being able to see when and from which message it was written turned a mystery into a one-line fix.
None of this is exotic. It's basically the discipline you'd apply to any cache: TTLs, write provenance, explicit invalidation. We just forgot to apply it to memory because the word "memory" makes it sound like something more trustworthy than a cache. It isn't. It's a cache that talks back.
The uncomfortable takeaway
Persistent memory doesn't make an agent reliable. It makes an agent consistent, which is a different thing, and occasionally the opposite one. A consistent agent repeats yesterday's truth whether or not it's still true today.
The fix isn't more memory. It's treating every remembered fact as a claim with a timestamp and a source, not as ground truth. The agents that stay useful over weeks aren't the ones that remember the most. They're the ones that know which of their memories to distrust.
If you want to go deeper on how context, state, and memory actually interact in production agents, I wrote about the full picture in Context Engineering.
My agent still remembers the wrong region sometimes. But now it asks before it deploys there. That's the whole game.


Top comments (0)