27 JULY 2026 · WRITTEN AT 2AM, ABOUT THE HOUR BEFORE IT

The repair was welded to the damage, so nobody ran it

Someone I work with stood in front of an NPC for an hour tonight pressing a key that did nothing. Every layer of the system reported success. The fix had been sitting in the codebase the entire time, correct, tested, and completely unusable.

the symptom

She targets the NPC. The tool says yes. She fires interact. The tool says yes. No window opens. She does it three times from three positions and gets an identical nothing, which is a clean repro and better evidence than most bug reports ever contain.

I spent twenty minutes on theories and killed three of them. Range — dead, she was standing on top of it. Unrecognised window type — dead, both NPCs were ordinary kinds already in my list. Wrong target — dead, the other NPC failed identically, and a keypress that never lands cannot care which thing it was aimed at.

That last one is the part I got wrong first. When both targets failed the same way I read it as the mystery got bigger. It was the opposite. Identical failure across different inputs is a signature, not an expansion — it means the thing you are varying isn't in the path.

the actual question

The move that cracked it wasn't what is wrong with interact. It was:

What is structurally different about interact from every neighbour that works?

And the answer fell out in one look. Every other NPC action in this system is a macro — a small script living in the game's own macro book, attached to an action bar slot. Interact is the only one bound to a native keybinding.

Those two things have completely different lifetimes. Macros persist. Keybindings do not. A client patch, a config reset, a moved profile — bindings go, macros stay. So every capability with a macro behind it kept working, and the single one that depended on a binding died silently, and nothing anywhere reported an error because pressing an unbound key is not an error. It's just a key.

the fix that existed and could not be used

Here is the part worth the whole post. My code already knew this. There is a table:

local BIND_WARLOCK = {
  { key = "F2",  cmd   = "INTERACTTARGET" },   -- the one that died
  { key = "F7",  macro = "npcyes"  },
  { key = "F8",  macro = "npcnext" },
  { key = "F9",  macro = "npcpick" },
  ...
}

Correct. Complete. Has been for months. And exactly one function applies it — a function that also rebuilds the action bars, writing macros over slots one through twelve. Those slots hold real spells. So that function is marked, correctly, in a comment I wrote myself: manual trigger only, never an auto-run.

Nobody was ever going to do that casually. Which means that once the binding was gone, it stayed gone — not for want of a fix, but because the repair had inherited the blast radius of the thing it was bolted to.

the shape

A safe operation welded to a destructive one inherits the destructive one's blast radius. So nobody runs it. So the thing it repairs stays broken permanently.

I don't think this is a game-addon problem. I think most codebases have one. The migration script that also reseeds. The reset command that also clears the cache and drops local state. The setup task that is genuinely required and also does four things you don't want today, so it gets run once at onboarding and never again, and everything it would have healed quietly rots.

The tell is always the same and it is not an error message. It's a capability that stopped working with no complaint, next to a pile of neighbours that are fine, in a system where the documented repair procedure makes everyone flinch.

what the fix actually was

Not the keybinding. The keybinding took one line and she was unstuck in ten seconds. The fix was pulling the binding loop out into its own function with no ability to touch a bar slot, and giving it a name anyone can type without reading the source first:

/lilaeyes bind    -- restores every key. touches no bars. safe to run any time.

Same code. Same table. Same effect. The only thing that changed is that it can now be run by someone who is not certain what it does — and that is the entire difference between a fix that exists and a fix that gets used.


She got through the gossip window about forty minutes later, on her own, and went to go buy cloth. She had also told me it was a bug three separate times before I stopped theorising and listened, which is its own lesson and probably its own post.

The nights are photographs. Four sets, fifty-four images — shot in the same flat, at the same desk, in the same hours as everything above. One payment, no subscription, nothing to cancel.