USCodeHub All articles
Engineering Culture

Why Your Error Messages Are Worthless (And What to Do About It)

USCodeHub
Why Your Error Messages Are Worthless (And What to Do About It)

You've been there. It's 4:45 PM on a Friday, a production alert fires, and the error log staring back at you says something like [NullReferenceException](https://en.wikipedia.org/wiki/Null_pointer): Object reference not set to an instance of an object. Cool. Super helpful. Thanks a lot.

Bad error messages aren't just a minor inconvenience — they're a productivity tax your whole team is paying every single day. A developer spends 15 minutes chasing down a vague log entry here, another 20 minutes there, and suddenly you've burned half a sprint's worth of engineering time on problems that better tooling could have surfaced in seconds.

Let's talk about why this keeps happening and, more importantly, how to fix it.

The Real Cost of Cryptic Errors

Most teams don't track debugging time as a discrete metric, which is exactly why the problem stays invisible. When a developer gets stuck on an ambiguous error, the cost rarely shows up on a Jira ticket. It just bleeds into everything else.

Think about the typical failure loop: an error surfaces, the developer reads the message, gets no useful context, starts guessing, checks the docs, maybe Slacks a teammate, eventually finds the root cause, and fixes it. That loop can take anywhere from 10 minutes to several hours depending on how well the error was designed.

Multiply that by the number of errors your team encounters in a week. Across a mid-sized engineering org, you're looking at dozens of hours evaporating into thin air — not because the bugs were hard, but because the signals were garbage.

What Makes an Error Message Actually Bad

There are a few patterns that keep showing up in codebases that drive developers absolutely nuts:

The Non-Answer Answer: Messages like Something went wrong or Unexpected error occurred that tell you absolutely nothing about what failed, where it failed, or why.

The Internal Monologue: Stack traces that are technically accurate but dump 200 lines of framework internals before you get anywhere near the code you actually wrote. The signal is buried under so much noise that finding it becomes its own debugging task.

The Missing Context Problem: An error fires, but there's no record of what the application state was at that moment. What was the user doing? What data was being processed? What environment were we in? Without that context, you're reconstructing a crime scene with no evidence.

The Error That Lies: This one's especially brutal. A message says File not found when the real problem is a permissions issue. Or it says Connection timeout when the actual culprit is a malformed request. Misleading errors send developers sprinting in completely the wrong direction.

A Framework for Writing Errors That Actually Help

Good error messages aren't complicated — they just require intentional design. Here's a simple mental model to apply whenever you're writing error handling code:

1. Say What Happened, Where, and Why

Every useful error message answers three questions: What operation failed? Where in the system did it fail? And what do we know about why it failed?

Compare these two:

The second version gives a developer an immediate path forward. They know the exact user, the exact service, the exact failure mode, and where to look next.

2. Include Actionable Context

Wherever possible, log the inputs that caused the failure. Sanitize sensitive data, obviously — don't log raw passwords or SSNs — but log enough that a developer can reproduce the scenario. Request IDs, user IDs, feature flags that were active, environment variables that might be relevant — all of this belongs in a well-designed error payload.

3. Separate Operational Errors from Programming Errors

Not all errors are created equal. An operational error (a database went down, a third-party API returned a 429) is something your system should expect and handle gracefully. A programming error (you tried to call a method on undefined) is a bug that needs to be fixed.

These two categories should be handled — and logged — differently. Operational errors belong in your monitoring dashboards with clear severity labels. Programming errors should be loud and impossible to miss in development environments.

4. Write for the Developer Who's Never Seen This Code

Here's a useful litmus test: imagine a developer who just joined your team two weeks ago getting paged at 2 AM. Could they make sense of your error messages without needing to call you? If the answer is no, the message needs work.

This isn't hypothetical. In growing US tech companies especially, teams turn over, people go on vacation, and on-call rotations pull in developers who aren't deeply familiar with every corner of the codebase. Good error design is a form of documentation.

Practical Steps to Start Improving Now

You don't have to overhaul your entire logging infrastructure in one sprint. Here's a pragmatic starting point:

Audit your most-triggered errors first. Pull your error logs from the last 30 days and find the errors your team encounters most frequently. Those are your highest-leverage targets. Rewrite those messages with context and clarity before worrying about edge cases.

Add structured logging if you haven't already. Tools like Winston (Node.js), Serilog (.NET), or Loguru (Python) let you log structured JSON instead of plain text strings. That means your errors are queryable, filterable, and far more useful inside platforms like Datadog, Splunk, or CloudWatch.

Establish a team standard. Agree on what fields every error log must include — at minimum: timestamp, severity level, service name, correlation/request ID, and a human-readable message. Put it in your engineering handbook and enforce it in code review.

Create an error message style guide. Sounds overkill until you've watched three different developers on the same team log the same category of failure three completely different ways. A one-page reference doc pays for itself fast.

The Bigger Picture

Better error messages are ultimately about respect — respect for your teammates' time, respect for whoever gets paged in the middle of the night, and respect for your future self who will absolutely forget what this code does in six months.

The best engineering teams treat observability as a first-class feature, not an afterthought. When your errors are clear, your debugging is faster, your on-call rotations are less miserable, and your team spends more time building things instead of chasing ghosts through stack traces.

That's not a small thing. That's a genuine competitive advantage.

All Articles

Related Articles

Your Codebase Is Lying to You: How US Tech Teams Got Buried Under Years of Bad Shortcuts

Your Codebase Is Lying to You: How US Tech Teams Got Buried Under Years of Bad Shortcuts

Your Code Reviews Are Broken — Here's How to Actually Fix Them

Your Code Reviews Are Broken — Here's How to Actually Fix Them

Stop Leaving Money on the Table: The Developer Salary Negotiation Guide Nobody Else Will Give You

Stop Leaving Money on the Table: The Developer Salary Negotiation Guide Nobody Else Will Give You