Blog Memory and context

How to Stop Your Coding Agent From Making the Same Mistake Twice

A concrete test for which fixes are worth writing down, and where to put them so the next session actually reads them before it acts.

a worn engineering notebook open on a dark desk beside a mechanical keyboard, handwritten diagrams visible, single warm lamp, night
Photo from Unsplash

The short answer

A coding agent repeats a fixed mistake because each session starts with a blank context window and no memory of what the last session learned. The fix is not a better model or a longer prompt: it is writing the specific failure down as a short rule, in a file the agent reads automatically at the start of the next session, such as CLAUDE.md for Claude Code, AGENTS.md for Codex, or GEMINI.md for Gemini CLI. Claude Code's own documentation lists "Claude makes the same mistake a second time" as the trigger for adding an entry. General-purpose agent memory tools like Mem0 do not solve this, because they remember the user across conversations, not the codebase across sessions.

Your agent fixed the DATABASE_URL parsing bug on Tuesday. On Thursday, in a fresh session, it re-broke it by making the exact same wrong assumption about how the connection string gets built. Nothing about the model changed between Tuesday and Thursday. What changed is that Thursday's session never saw Tuesday's fix. This post covers the narrow, mechanical fix for that: deciding what is worth writing down, and where to put it so the next session reads it before it acts. It does not cover prompt engineering tricks or picking a different model.

The shape of the bug is the blank slate, not the model

Claude Code's own documentation puts it plainly: "each Claude Code session begins with a fresh context window." Nothing from the previous conversation survives into it, not the bug you fixed, not the workaround you found, not why you rejected the obvious approach. Two mechanisms carry knowledge forward, and both require writing something down on purpose: CLAUDE.md files you author, and an auto memory layer Claude writes for itself from your corrections. Skip both, and tomorrow's session knows exactly as much about the project as this morning's session knew before you said a word.

This is not a model quality problem. A more capable model reasons better inside the context it has; it does not invent context it was never given. Blame the wrong actor and you end up trying to fix this with a longer prompt, which helps for exactly one session and evaporates with it.

Agent memory and project memory are not the same thing

Search for "AI agent keeps forgetting" and most of what comes back is agent memory: products like Mem0, whose README describes a layer that gives assistants "personalized AI interactions" by remembering a user's preferences and history across conversations, or Hindsight, a research system that reached 91.4% accuracy on a long-memory benchmark with a scaled-up backbone model, by organizing an agent's experience into fact, episode, and belief networks. Both are real. Neither is about your codebase.

Agent memory remembers you: your tone preferences, that you asked about Stripe webhooks last week in a different repo. Project memory remembers the project: that staging uses a different connection pooler than production, that the CSV export silently truncates at 10,000 rows because of a library default. The first kind follows a person everywhere. The second has to stay tied to the codebase and shared with everyone touching it, including a teammate's Codex session in an entirely different repository that has never talked to your Claude Code session. A 2026 paper on exactly this gap, PROJECTMEM, frames it as a missing "judgment layer" and estimates that reconstructing lost project context this way costs an estimated 5,000 to 20,000 tokens every session it has to happen.

What a gotcha actually is, and what it is not

A gotcha is a specific, non-obvious fact that will cause a specific, predictable failure if the next session does not know it. "The migration script has to run with --seq, not in parallel, because two seed tables have a foreign key ordering dependency Postgres won't catch until it's too late" is a gotcha. "Be careful with migrations" is not. The second sentence carries no information an agent can act on differently; it is a mood, not a rule.

What a gotcha is not:

  • A restatement of something visible in the code. Claude Code's own auto memory explicitly skips saving anything it can derive from the codebase, and a hand-written note should follow the same rule.
  • A design preference with no failure attached. "We prefer functional components" is a style rule for a linter or a CLAUDE.md conventions section, not a gotcha, because ignoring it does not break anything.
  • A one-time fact about today. "The staging server is down until Friday" will be false by the time anyone reads it back.
5,000-20,000
Estimated tokens an agent burns per session reconstructing project context that was never written down. PROJECTMEM, 2026

The three-question admission test before you write anything down

Before a fix, a workaround, or a hard-won discovery earns a permanent line in a memory file, run it through three questions:

  1. Does this only make sense inside this specific project? If the fact is really just "how Postgres foreign keys work," the agent already knows it or can look it up; it does not belong in project memory at all.
  2. Will this still be true in six months without anyone updating it? A number, a date, or a "for now" state fails this question and should go somewhere else, or nowhere.
  3. Without this note, will the next session actually get it wrong or redo work that was already done? If the honest answer is "probably not, it would just be slightly less efficient," it is not worth the context budget.

All three have to be yes. This is a deliberately high bar, and that is the point: a memory file that admits everything stops being read carefully, which defeats the purpose of having one.

Anatomy of a note worth keeping: hook, cause, rule

The gotchas that survive rereading, months later, by someone who was not there when they were written, share a three-part shape:

  • Hook: the trigger that should make an agent think of this note. Usually a file path, a command, or a symptom. "When touching migrations/."
  • Cause: the one sentence of why, so the rule does not look arbitrary and does not get "cleaned up" by a future session that does not understand it. "Two seed tables have a circular foreign key dependency Postgres only enforces at insert time."
  • Rule: the specific, checkable instruction. "Always run migrations with --seq, never in parallel."

Compare that to a typical bad note: "migrations can be tricky, double check before running." No hook to attach it to a specific action, no cause to explain why, no rule specific enough to verify. An agent reading that note before touching migrations/ learns nothing it can act on differently.

A developer annotating a printed architecture diagram with a red pen next to a laptop terminal.
The record that matters is the one written down before the next session starts, not the one buried in a diff.

Where to put it so the next session reads it before it acts

The note only works if it loads automatically, before the agent does anything, not if it lives somewhere the agent has to remember to go look. Claude Code, Codex, and Gemini CLI each use the same mechanism under a different filename:

Agent File Loaded from What it's for
Claude Code CLAUDE.md project root and every parent directory, at session start Documented reason to add a line: Claude makes the same mistake twice
Codex AGENTS.md nearest file up the directory tree Team-specific build, test, and review conventions
Gemini CLI GEMINI.md working directory and every parent up to the project root Any instruction otherwise repeated in every prompt

If you run Claude Code alongside Codex on the same repository, avoid maintaining duplicate instructions: Claude Code will import an existing AGENTS.md with a one-line @AGENTS.md reference at the top of CLAUDE.md, or a symlink from CLAUDE.md to AGENTS.md, rather than requiring a separate file. A full side-by-side of what each format supports, including where GEMINI.md fits in, is in the comparison of CLAUDE.md, AGENTS.md, and GEMINI.md. What matters here is narrower: whichever filename you use, keep it short enough that it still gets read carefully rather than skimmed past.

Why the fix cannot live in the commit message

The commit that fixed the bug is a perfectly good record of what changed. It is a bad record for the next session's agent, because nothing loads it automatically. An agent does not scan git log before every action; it would have to be told to search history for the specific file, guess the right keywords, and read through commits that may or may not still be relevant. That is the reconstruction cost the PROJECTMEM estimate above is describing. A memory file is different specifically because it loads whether or not anyone thinks to ask for it. The commit message answers "what happened." The gotcha has to answer "what do you need to know before you touch this again," and only one of those gets read on session start.

Work still to be done is not memory, and memory is not a backlog

It is tempting to dump everything into the same file: the gotcha about migrations, next to a note that says "still need to add rate limiting to the export endpoint." Keep them apart. A gotcha is a fact about the past that constrains future behavior. A task is work that has not happened yet. Mixing them means the agent has to reread completed work every time it is scanning for what to do next, and the actual backlog gets buried in a wall of historical trivia. An issue tracker, whether that is a plain markdown file with checkboxes or a hosted board, is where "still needs doing" belongs. The memory file is where "this is why the thing that got done was done that way" belongs.

This is the gap Trail is built to close: a hosted issue tracker an AI coding agent writes to directly over the Model Context Protocol, where project reference memory is a layer separate from the task board that every session reads automatically on opening the project, shared across every person and every agent working on it rather than sitting in one person's local CLAUDE.md. The agent that just hit the gotcha writes the note itself, in the same conversation, instead of you transcribing it into a file by hand afterward.

Pruning: a memory that has gone stale is worse than no memory

A note that is wrong is more dangerous than a note that is missing, because a missing note produces a mistake you can catch and fix, while a wrong note produces confident, wrong behavior that looks deliberate. Claude Code's documentation warns about exactly this decay: it says to review CLAUDE.md files periodically to remove outdated or conflicting instructions, and separately notes that files over 200 lines "consume more context and reduce adherence." Both point at the same failure mode: a file that only ever grows becomes a file nobody, human or agent, fully trusts, a decay this same site covers in more depth in why an oversized CLAUDE.md gets ignored. Delete or correct an entry the moment it stops being true, the same day you notice, not on some future cleanup pass that never comes.

What this looks like once the agent maintains it itself

The version of this that survives is the one where writing the note is not a separate chore left for after the fix ships. The same conversation that hit the gotcha and fixed it is also the one still holding the cause, which makes it the best place to write the hook-cause-rule note down while it is fresh, whether that is an agent updating its own auto memory file or updating a shared project record directly. The discipline this whole post describes, the admission test, the three-part shape, the pruning habit, does not disappear once the agent is the one holding the pen. It just moves from something you enforce by hand to something you audit afterward, which is the only version of this that keeps up with a project that changes every week.

Verdict

If you are working solo in one repository with one agent, a CLAUDE.md file you maintain by hand, checked against the three-question test above, is enough, and free. The moment a second agent, a second repository, or a second person enters the picture, a plain file per project stops being enough on its own, because nothing forces the note to be written at the moment the mistake happens or keeps it visible to everyone touching the code, which is exactly where context starts bleeding between projects that were never supposed to share it. Start with the file. Add a shared, agent-writable layer once more than one agent or one person depends on the same project not repeating what it already learned.

What to remember

  • Claude Code documentation states that each session begins with a fresh context window, so nothing from a prior session persists unless it was written to a file the agent reads back.
  • Anthropic's own guidance names "Claude makes the same mistake a second time" as one of the four triggers for adding a line to CLAUDE.md.
  • Agent memory products such as Mem0 and Hindsight persist facts about the user and the conversation, not facts about a specific codebase, so they do not stop a re-broken build script.
  • A 2026 arXiv paper on project memory for coding agents, PROJECTMEM, estimates that reconstructing lost project context costs 5,000 to 20,000 tokens per session when it is not written down.
  • Both Codex's AGENTS.md and Gemini CLI's GEMINI.md are loaded automatically at the start of a session, the same mechanism Claude Code uses for CLAUDE.md.
  • A gotcha worth keeping names a specific trigger and a specific rule; a vague reminder to "be careful" does not survive contact with the next session.

Questions people ask

Why does my AI coding agent keep making the same mistake?

Because most agents do not carry anything from one session to the next by default. Claude Code's own documentation states that each session starts with a fresh context window, so a fix you explained on Tuesday is gone by Thursday unless it was written into a file the agent reads automatically, such as CLAUDE.md, AGENTS.md, or GEMINI.md.

Is agent memory the same thing as project memory?

No. Agent memory, the kind sold by tools like Mem0 and Hindsight, remembers facts about you and your past conversations across different projects. Project memory remembers facts about one specific codebase, such as which build flag breaks the deploy, and needs to be shared with every person and every agent touching that project, not tied to one person's account.

Should everything the agent learns go into CLAUDE.md?

No. A file that only grows becomes noise the agent skims past, and Claude Code's documentation notes that files over 200 lines consume more context and reduce how reliably instructions are followed. Keep only what would make the next session fail or redo work without it, and prune entries that stop being true.

Can git commit history replace a memory file?

Not reliably. An agent does not read commit messages before acting unless it is explicitly told to search git log for the relevant file first, and most sessions do not do that. A gotcha needs to be somewhere loaded automatically before the first action, not somewhere it has to think to look.

Does this work the same way for Claude Code, Codex, and Gemini CLI?

The mechanism is the same across all three even though the filename differs. Claude Code loads CLAUDE.md, Codex loads AGENTS.md, and Gemini CLI loads GEMINI.md, all read automatically from the project directory at the start of a session, so the same short-rule format works in any of them.

Keep reading