Beer & Servers Don't Mix

The Solutioneering Trap: Why Your Best Engineers Are Solving the Wrong Problems

Or: How a Perfectly Good Prototype Taught Me We Were Asking the Wrong Question

Somchai had that look. You know the one — the barely-contained electricity of an engineer who’s been up late building something they can’t wait to show you. He’d booked the small meeting room on the sixth floor, the one with the busted aircon that always smells faintly of Thai iced bubble tea and whiteboard marker. His laptop was already open, screen angled toward the empty chair, a prelive URL glowing in the browser tab. The Bangkok afternoon sun was flooding through the floor-to-ceiling glass, turning his screen into a mirror, but nothing was dimming that grin.

He’d built it. End to end. A working prototype — one page, granted, but a compelling one — replacing our Razor server-side rendering with Next.js, React components rendered server-side, full HTML coming down on first load — LCP improvements that would make any performance engineer’s heart sing. He clicked through it with the careful pride of someone showing you their first apartment. Every page transition was buttery. Every component hydrated cleanly. It was, by any reasonable measure, impressive work.

And I sat there with the sinking realisation that I was about to be the person who dims that light.

Not because the work was bad — it wasn’t. It was absolutely amazing. Not because the idea was wrong — it wasn’t entirely. But because Somchai had done what our best engineers always do: he’d fallen in love with a solution before he’d finished falling in love with the problem. And now I had to walk him back through a door he didn’t even know he’d skipped past.

That scene — the brilliant prototype that solves the wrong problem, or solves the right problem at ten times the necessary cost — plays out in engineering organisations every single day. We have a word for it, though it’s not one you’ll find in most textbooks: solutioneering. It’s the engineering equivalent of what Abraham Maslow described when he observed that if the only tool you have is a hammer, everything looks like a nail. Except in our case, the hammer is whatever technology we’re most excited about this month, and the nail is whatever vaguely related problem sits closest.

Solutioneering isn’t laziness. That’s what makes it so dangerous. It’s the opposite — it’s enthusiasm, expertise, and initiative all pointed in a direction that nobody stopped to verify. It’s your most capable people burning cycles on technically excellent work that misses the mark, and it happens precisely because they’re good enough to build things without needing permission or a roadmap.

The Problem with Starting at Solutions

Let me take you back to that meeting room with Somchai. After I’d admired the demo — and I meant it, the work was genuinely good — I started asking questions. Not to tear the idea down, but to understand the shape of the problem it was solving.

“Is there any other framework that could achieve the same thing we should consider?”

A pause. He hadn’t looked. Next.js was what he knew, what he was excited about, what the blogs and conference talks were buzzing about. It was the obvious choice — so obvious that considering alternatives felt unnecessary.

“Could we achieve this without rewriting all of our server-side rendering code?”

A longer pause. It turned out Razor actually has a library that does server-side rendering for React components. We didn’t need to replace the entire rendering pipeline. We could extend it.

“Is there another way to solve the same problem for less cost?”

And here’s where the real insight hit. The problem statement wasn’t “we need Next.js.” The problem statement was: we have no server-side rendered HTML. When you frame it that way, the solution space opens up dramatically. Yes, Next.js could solve it. So could React SSR inside Razor. And so could something less glamorous — serving skeleton HTML from Razor without any React SSR at all. That last option had its own trade-offs: you’d need to duplicate HTML in Razor for each page’s skeleton, which is maintenance overhead and not exactly elegant. But it would have arguably had a meaningful impact on LCP without touching the rendering pipeline.

Three solutions to the same problem. One required a platform migration. One required a new library integration. One required duplicating some HTML templates — unglamorous, imperfect, but a fraction of the effort. Every option had trade-offs. But we never got to weigh them, because we’d already committed to the most expensive one.

As the economist Charlie Munger once put it, “To a man with a hammer, every problem looks like a nail. But to a man with only a hammer, they tend to be very expensive nails.” Somchai’s hammer was beautifully engineered. But we’d skipped the step where we figure out whether we’re actually looking at a nail.

Solutioneering Is an Organisational Problem, Not an Individual One

Before we go further, I want to be clear about something: this isn’t Somchai’s fault. Somchai did exactly what our engineering culture rewards. He saw a problem, got excited, built something. We celebrate that initiative. We promote people who show that kind of drive.

The problem is that we’ve built engineering organisations where the path from “I noticed a problem” to “here’s my pull request” skips the most important step. We don’t teach engineers to sit with the problem. We don’t give them frameworks for exploring the problem space before they start typing. And when someone shows up with a working prototype, the social dynamics of the room make it almost impossible to say “but should we have built this at all?”

This hit me hard enough that we built something to catch it. Rather than redesigning the RFC process itself — adding more gates, more review meetings, more hoops — we created an LLM prompt that analyses RFCs for solution-first thinking. Using Claude and the right prompting, we made it deliberately opinionated. It doesn’t pull punches. If your RFC opens with three pages of architecture and a two-sentence problem statement tacked on like an afterthought, it will tell you — directly, specifically, and without the diplomatic softening that humans default to in professional settings.

The impact wasn’t what I expected. Engineers didn’t resent it — they loved it. Because here’s the thing about getting critical feedback from an LLM: it’s available on demand. You don’t need to schedule an expensive meeting with Directors and VPs, spend hours preparing a presentation, and walk into a room where the social dynamics make honest feedback almost impossible. You run your RFC through the prompt at 10 PM on a Tuesday while you’re still drafting, get direct feedback on whether you’ve actually defined the problem, iterate, and come to the review meeting with something that’s already been stress-tested. Early, direct, low-stakes feedback before you’ve gone too far — that’s the sweet spot where solutioneering gets caught before it becomes a two-week prototype.

Design Thinking: Not What You Think It Is

I know what you’re thinking. “Design thinking? That’s a UX thing. That’s sticky notes and empathy maps and workshops where people draw pictures.” And yes, that’s what it’s become in a lot of organisations — a sanitised corporate exercise that produces colourful wall decorations and very little else.

But strip away the Post-it notes and the UX jargon, and design thinking is essentially the scientific method applied to problem-solving. And when you present it through an engineering lens, it becomes something far more powerful than a workshop exercise. It becomes the antidote to solutioneering.

Let me walk through it the way I wish someone had walked Somchai through it before he opened his IDE.

Empathise — and I don’t mean “create a persona.” I mean understand the user’s actual workflow. Not the workflow described in the ticket, not the workflow the product manager imagines, but the one that exists in reality. In Somchai’s case, this meant understanding what actually happens when a user hits our page. What does the browser receive? What renders first? What does the user see while they wait? If you don’t understand the lived experience of the problem, you’ll solve for the abstraction instead of the reality.

Define — write a problem statement that could be measured. Not “we need better SSR” but “our pages serve no meaningful HTML on first load, resulting in a white page for a brief period and an LCP of X milliseconds — this could be improved.” A good problem statement is falsifiable. If you can’t measure whether you’ve solved it, you don’t understand it yet. This is where Somchai’s journey would have changed. “We have no SSR HTML” is a measurable problem. “We need Next.js” is not.

Ideate — and this is the hard part — resist the first solution. Generate at least three approaches before evaluating any of them. For Somchai’s problem, that looked like: (1) Next.js replacement of the rendering pipeline, (2) React SSR inside Razor using an existing library, (3) skeleton HTML served directly from Razor with no React SSR at all. And those were just the ones we came up with in that meeting room — there could easily have been more if we’d opened it up to the wider team. The discipline isn’t in generating ideas — engineers are great at that. The discipline is in not immediately latching onto the first one that feels technically interesting.

Prototype — but not a full prototype. The cheapest thing that tests the riskiest assumption. If the question is “will serving HTML improve LCP?” you don’t need a Next.js migration to answer it. You need a skeleton template on one page and a performance benchmark.

Test — put it in front of actual conditions. Not a local demo, not a prelive server with synthetic traffic, but real users generating real data that tells you whether your problem statement was correct and whether your solution addresses it.

Here’s the thing about design thinking that most engineers miss: it’s not a process to follow. It’s a discipline to practice. Each of those stages is something you’d naturally do if you slowed down. Empathise? That’s just “understand what you’re building and why.” Define? That’s “write a clear problem statement.” Ideate? That’s “consider your options.” Engineers do these things instinctively for technical problems — we’d never pick a database without comparing alternatives. We just forget to apply the same rigour to the problem itself.

The XY Problem and the Self-Similarity Principle

There’s a concept in Extreme Programming called the self-similarity principle — the idea that the same patterns and practices that work in one area tend to work in most others. If test-driven development is good for writing a function, the same feedback-loop discipline should apply to designing a feature, planning a sprint, or setting a quarterly roadmap. The pattern is fractal: define what success looks like, build the smallest thing that tests your assumption, measure, adjust.

Design thinking is self-similar in exactly the same way. It works when an individual engineer is deciding how to approach a coding task. It works when a team is scoping a project. It works when leadership is setting strategy. The area applied changes. The discipline doesn’t.

This connects to something we discovered in our tech lead training that I think is profoundly important: non-engineers tend to present problems pre-filtered through what they think engineering can solve. A product manager doesn’t come to you and say “our users are frustrated with the booking flow.” They come to you and say “we need a loading spinner on the confirmation page.” They’ve already done the problem-solving in their head — badly, because they don’t have the technical context — and presented you with what they think is a reasonable solution.

This is the XY problem at an organisational level. Someone has problem X, they assume solution Y, and they ask you to implement Y. When Y doesn’t fully solve X, everyone’s confused. Design thinking breaks this cycle because it teaches engineers to ask upstream questions. Not “how should this spinner behave?” but “what’s the user actually experiencing that made someone think a spinner was the answer?”

The Jobs-to-be-Done framework meshes naturally here. When you stop asking “what feature should we build?” and start asking “what job is the user trying to accomplish?”, the solution space explodes. That confirmation page loading issue might be better solved by pre-fetching data, by restructuring the booking flow, or by eliminating the confirmation page entirely. But you’ll never discover those options if you start at “build a spinner.”

From Feature Factory to Problem-Solving Organisation

We ran what we called a “Problem-athon” with our tech leads — essentially a workshop where instead of building solutions, teams competed to define the best problem statements. The feedback was fascinating, and a little uncomfortable.

Several participants said it was “harder to get back to regular sprint work” afterwards. Not because the workshop was draining, but because problem-finding was more engaging than ticket-completing. When you ask engineers to deeply understand a problem before solving it, they don’t find it tedious — they find it intellectually satisfying in a way that implementing a pre-specified feature rarely is.

The most telling feedback came from a tech lead who said that asking “what are your success metrics?” instead of “what do you want built?” completely changed his conversations with product managers. Not adversarially — collaboratively. When both sides focus on the outcome they’re trying to achieve, the conversation naturally moves from “build feature X” to “improve metric Y.” And a team trying to improve conversion rate on the booking funnel has design thinking baked into their DNA. A team building “feature X to specification Y” has solutioneering baked in.

As General Dwight Eisenhower observed, “Plans are worthless, but planning is everything.” The value of design thinking isn’t the five stages. It’s the discipline of staying with the problem long enough to actually understand it before you commit resources to a solution.

This is the bridge between engineering and product that most organisations are desperately looking for. Engineers who frame problems well don’t just build better features — they stop building unnecessary ones. They become partners in product thinking rather than implementers of product decisions. And the organisation starts shifting from a feature factory — where success is measured by what ships — to a problem-solving engine, where success is measured by business impact.

Measure Twice, Cut Once — Then Measure Again

If I could encode design thinking into a single engineering principle, it would be this: the cost of building the wrong thing always exceeds the cost of taking time to understand the problem.

Somchai’s Next.js prototype took two weeks and covered one page. The skeleton HTML approach that we eventually explored required duplicating templates per page — real maintenance overhead, not a trivial change. But it was still a fraction of the cost of a platform migration, it improved LCP, and it shipped to users sprints earlier than a Next.js rewrite ever could have. The Next.js version was more technically elegant, more architecturally interesting, and would have made for a better conference talk. But elegance wasn’t the problem we were solving.

I’m not saying the quick-and-dirty option is always the right one. Sometimes the bigger investment is justified — when the problem space is well-understood, when the success metrics are clear, and when you’ve genuinely evaluated the alternatives. But that evaluation has to happen first, not after someone’s already built a prototype they’re emotionally invested in.

As the carpenter’s proverb goes — one that predates software by centuries — “measure twice, cut once.” We’ve gotten remarkably good at cutting. It’s the measuring we keep skipping.

The Bottom Line

Design thinking isn’t a UX workshop. It’s not sticky notes on a wall. It’s the discipline of understanding problems before solving them, and it’s as fundamental to good engineering as testing, code review, or version control.

Solutioneering — jumping to solutions before defining problems — isn’t a character flaw. It’s a natural consequence of working in organisations that reward shipping over understanding, and staffing those organisations with brilliant people whose instinct is to build. The fix isn’t to dampen that instinct. It’s to channel it. Define the problem first. Articulate what success looks like. Generate options. Test the cheapest assumption. Then build.

The self-similarity principle tells us this discipline should be fractal — applied by individual engineers to coding decisions, by teams to project scoping, by leaders to strategy. The organisations that get this right don’t just ship better features. They ship fewer unnecessary ones, which is worth far more.

Now, if you’ll excuse me, I need to go review an RFC. Someone’s proposed a microservices migration to solve a problem that I’m fairly sure is a misconfigured cache. But the architecture diagram is beautiful, so at least there’s that.