Writing

Keep a Gotchas File Your AI Reads Before It Repeats Your Mistakes

Keep a Gotchas File Your AI Reads Before It Repeats Your Mistakes - abstract illustration

There's a specific class of failure an AI can't reason its way out of: the case where reality contradicts what the model was trained to expect. A function that returns false instead of throwing. A tool that reports success while doing nothing. A timezone that shifts a value fourteen hours in the wrong direction. The model has seen the "correct" version of that API ten thousand times in training, so it confidently does the correct thing, and the correct thing is wrong in your environment. The fix isn't a smarter model. It's a file the model reads first.

I keep that file in every project. It's the companion to the authoritative reference library that tells the AI how things are supposed to work. The gotchas file tells it how they actually behave when they misbehave.

Why a model can't infer these

A language model is very good at the median case. It generalizes from the enormous number of examples where an API behaves as documented. That's exactly why the exceptions are lethal: they are, by definition, the cases the training data underrepresents or gets wrong.

Think about what the model "knows" about a filesystem move operation. It knows that a rename either succeeds or raises an error you can catch. So when my MCP filesystem tool silently returns false and does nothing when the target filename contains a comma, the model has no prior knowledge of that. It calls the tool, gets false, and in the absence of any warning, it does one of two bad things: assumes success and moves on, or burns three turns inventing theories about permissions and path encoding. Neither is recoverable by reasoning, because the behavior isn't reasonable. It's a quirk of one specific implementation.

That's the tell for something that belongs in the gotchas file. If a competent engineer would need to have been burned once to know it, the model needs to be told, because it wasn't in the room when you got burned.

What an entry looks like

I keep entries boring and uniform on purpose. One gotcha per entry. Symptom first, because the symptom is what you (or the AI) will be staring at when you go looking. Then the root cause. Then the workaround. Greppable, so a search for the error string or the tool name finds it.

A real one from my vault, lightly formatted:

  • Symptom: moveFile returns false and the file is not renamed. No exception, no error message.
  • Root cause: The MCP filesystem tool silently fails when the destination filename contains a comma. It affects renames specifically.
  • Workaround: Shell out to mv for any rename whose target name contains a comma. Do not trust the boolean return of the MCP move for these.

Another, because this one cost me a genuinely confusing afternoon:

  • Symptom: Obsidian tools report a path as missing or return empty results for a folder I can see exists, e.g. a folder named with an ampersand.
  • Root cause: The path was passed with the HTML entity & instead of a literal &. The tool does not decode it, so it looks for a folder that does not exist and returns a clean false negative.
  • Workaround: Always pass a literal & in vault paths. Never let an entity-encoded ampersand reach the tool.

Note what both entries have in common: the failure is silent and the return value lies. There's no stack trace to paste. Those are precisely the ones worth writing down, because there's nothing for the model to catch and react to at runtime. The only defense is prior knowledge.

The timezone and epoch traps

The two most expensive gotchas I've logged both involve numbers that look plausible while being completely wrong. Plausible-but-wrong is the worst category, because nothing crashes.

The off-by-fourteen-hours cutoff. One of my planner agents computes a "process emails since" cutoff. It was adding a UTC offset where it should have subtracted, advancing the cutoff roughly fourteen hours into the future. The agent didn't fail. It just quietly skipped every email that arrived in that window, every run. There's no error state for "your date math is directionally wrong." I only found it by noticing emails that should have been processed were not. The gotchas entry names the agent, the direction of the bug, and the correct operation, so the next time anything touches that cutoff, the AI reads the warning before it re-derives the same mistake from first principles.

The epoch with an extra 000. A scheduler passes a start time into an agent prompt. The convention across most of my jobs is that the value arrives in seconds, and you append 000 to get milliseconds. One job already delivers the value in milliseconds. Append 000 anyway and you get a 16-digit epoch, roughly a thousand times too large, pointing somewhere around the year 50,000. Again: no crash. Just a duration calculation that comes out absurd. The entry tells the AI to sanity-check any epoch against the current time before trusting it, and specifically flags that one job as already-in-milliseconds.

The pattern across all four examples is the same. The model does the textbook-correct thing (\${START_EPOCH} in seconds, so append 000; ampersands are just characters; a move either works or throws) and the textbook is wrong for that spot. A gotchas file is where you record every place your world diverges from the textbook.

How the file gets populated

There's exactly one rule, and it's a discipline rather than a system: every time you debug something non-obvious, write it down before you close the ticket in your head.

The moment to capture it is the moment you understand it, when you have the symptom, the root cause, and the fix all loaded in working memory at once. An hour later you'll have the fix but not the crisp symptom, and the symptom is the part that makes the entry findable. If you or your AI just spent four turns untangling why a tool did nothing, that four-turn cost is a one-time payment only if you record the result. Skip the write-up and you'll pay it again next month, probably at 11pm.

I don't try to seed the file speculatively. A gotcha earns its place by having actually bitten someone. A theoretical edge case that never fires is just noise that dilutes the entries that matter. The file grows from real scars, which is what keeps its signal-to-noise high enough that reading it is worth the tokens.

How the AI is told to consult it

Writing the file down is half the job. The other half is making sure the model actually opens it before it acts, not after it's already fallen in the hole.

I wire that in at the instruction layer. In the project's CLAUDE.md and in the relevant agent definitions, there's a standing directive: before working with a given tool or subsystem, check the gotchas file for known issues. For the highest-traffic traps I go further and put a one-line pointer right where the work happens, so the instruction to check is physically adjacent to the operation that triggers the bug. A note next to the date-math step that says "epoch may already be in ms, verify" costs almost nothing and catches the failure at the exact moment it would occur.

For agents that run unattended, this matters more than for interactive sessions. When I'm at the keyboard, I can catch a wrong result and redirect. My production agents run on a schedule with no one watching, so the only thing standing between a known gotcha and a silently corrupted run is whether the instructions steered the model to the file first. The gotchas file plus the directive to read it is, in practice, how I encode "we already learned this" into a system that otherwise starts every session with no memory of yesterday.

The compounding effect is the real payoff. Each entry is a mistake that can only cost you once. A model with no persistent memory will happily rediscover the comma bug, the ampersand bug, and the epoch bug on a loop forever, because from its perspective every session is the first one. The gotchas file is the institutional memory the model doesn't have on its own, and unlike a smarter model, it's something you can build this afternoon with a text file and the discipline to keep it current.

Building something like this?

This is the kind of work I do for clients. Tell me what you're building and I'll give you a straight read on the approach.

Book a 30-minute call