Jake Worth

Jake Worth

Broken Mental Model

Published: July 25, 2022 2 min read

  • debugging

Perhaps you’re familiar with this scenario: you’re debugging and you’re stuck. You’ve Googled and read some blog posts, Stack Overflow answers, and documentation.

You pull up your search engine, type a question, and then something unusual happens: your search engine autocompletes your question. You’ve asked it verbatim before. The results are all purple because they have been visited by you.

The internet is out of answers. What now?

When this happens, I’ve come to classify the culprit as (almost always) a broken mental model.

But first, when is a bad mental model not the culprit? I can think of one exception, and that’s when you’re innovating.

The Innovation Exception

Are you building a new language or framework? Are you connecting two different things, like proprietary closed-source software products? Maybe you’re trying to get a microwave oven to move a satellite. Are you innovating?

Software is so new, and changes so fast, that it’s possible to find yourself in such a situation.

If that’s you, awesome! Onward. For the rest of us, read on.

Broken Mental Model

When I see that wall of visited links, I see a broken mental model.

A broken mental model is an incorrect understanding of how something works. It derails the problem-solving process by leading us to ask bad questions. Bad questions equal bad answers.


A real example from my recent work was learning how Angular.js handles reactivity.

I had an Angular callback function. That function was being called by the same Vue component in two different contexts.

When the user clicks a button in the first context, the function is called and a modal appears. That same behavior in the second context also calls the function, but then that inscrutable event occurs: “nothing.” No modal. Shouldn’t a function, called twice with the same arguments, cause the same results?

I spent too long typing half-baked questions into Google like “Angular state not updating” and “Angular watch delay on scope change.” Never finding anything close to an answer.

After marinating in this state, I had the realization this post is about. I had a broken mental model.

When you get there, go back to first principles. Stop programming, and start explaining your thoughts to someone else. If you don’t have other people, start reading the official docs for the tool that’s giving you problems. Build a correct mental model.

In my case, I cracked open the official Angular.js docs and started reading about reactivity. Not React or Vue reactivity, but Angular.js reactivity.

I learned about the Angular digest cycle, a core idea of that framework. Angular has a series of built-in functions called directives, which handle events like clicks. When one of those directives is called, the framework reacts in a process called the digest cycle. It happens automatically, except when state is changed outside of an Angular directive. Angular doesn’t know the state has changed and doesn’t react. That second function call, the one not triggering the digest cycle, happened outside of Angular.

Once I had a mental model, I found the canonical solution: manually triggering the digest cycle with $apply.

I started thinking correctly about the system, and the answer appeared.


I hope this post has helped you learn to recognize broken mental model and provided a path forward.

What are your thoughts on this? Let me know!

Get better at programming by learning with me! Join my 100+ subscribers receiving weekly ideas, creations, and curated resources from across the world of programming.