How I Handle a Serious Bug When I'm Responsible for Everything

 


A serious production bug feels different when there is no separate operations team, support team and backend team.

The same person who wrote the feature may be the person reading the error, answering the user, checking the database and deciding whether the whole system should be taken offline.

That is the reality of building independently.

The biggest lesson I have learned is that the first job during a serious bug is not to prove I can fix it quickly.

The first job is to reduce damage and create enough clarity to make a correct decision.

I define "serious" by impact, not by how scary the error looks

A giant stack trace can come from a low-impact feature.

A quiet wrong calculation can be much more serious.

I treat a bug as high priority when it could involve:

  • security;
  • unauthorized access;
  • incorrect financial state;
  • loss or corruption of data;
  • an unavailable core workflow;
  • many users;
  • a problem that gets worse while the system remains active.

The category changes my response.

A broken icon can wait.

A permission bug cannot.

Step 1: contain before rewriting

When the system is actively causing harm, I stop the harm.

Depending on the issue, that could mean:

  • disabling one feature;
  • rolling back the latest deployment;
  • turning off a risky integration;
  • putting a workflow into maintenance;
  • restricting access;
  • pausing a scheduled process.

I do not immediately rewrite 300 lines while the same failure keeps happening.

Containment buys time.

Step 2: preserve evidence

Before clearing logs or changing data, I collect what I need to understand the event.

I record:

  • time;
  • affected URL/feature;
  • user action;
  • error message;
  • request ID or transaction reference if one exists;
  • deployment version;
  • recent changes;
  • relevant logs.

If personal or sensitive information is involved, I handle it carefully.

The point is to preserve the technical story, not to copy private user data into random notes.

Without evidence, every later theory becomes harder to prove.

Step 3: write the symptom in one sentence

I force myself to describe the problem clearly.

For example:

Authenticated users can view their own profile, but updates started returning 403 after today's database-policy change.

That sentence is much more useful than:

Profiles are broken.

It tells me:

  • authentication exists;
  • read permission works;
  • update permission does not;
  • timing may connect to a policy change.

The sentence does not solve the bug.

It prevents me from debugging the entire application at once.

Step 4: check what changed

Recent changes are not always the cause.

They are still a good place to start.

I review:

  • latest deployment;
  • dependency updates;
  • environment variables;
  • DNS changes;
  • database migrations;
  • authentication settings;
  • provider configuration.

If the bug started immediately after a release, rollback may be safer than investigating on production while users remain affected.

A rollback is not failure.

It is a tool.

Step 5: reproduce safely

I want a repeatable case.

If the bug affects user-owned data, I reproduce with test accounts where possible.

If it involves payments or destructive actions, I avoid creating real financial or data damage simply to prove the bug exists.

A reproduction should answer:

What exact sequence makes this happen?

Once I have that, I can test fixes instead of relying on hope.

Step 6: identify the failing layer

I move through the system.

Browser/UI

Did the handler run?

Is the submitted data correct?

Network

Did the request leave?

What status came back?

Authentication

Is the session valid?

Authorization

Is this identity allowed to perform this action?

Backend/database

Did the operation fail?

Were constraints violated?

Third party

Did an external API reject or delay the request?

This layer-by-layer approach stops a backend policy problem from turning into a React rewrite.

Step 7: fix the smallest root cause I can justify

Under pressure, big changes are risky.

If I can identify one policy, one condition or one regression that caused the incident, I prefer a focused fix.

I do not combine the emergency patch with unrelated cleanup.

This is not the moment to rename folders.

The goal is to restore correct behavior with the smallest understandable change.

Step 8: verify the fix beyond the original case

A fix can solve the reported case and break another.

I test:

  • the original failure;
  • the normal success path;
  • related permissions;
  • another user account;
  • refresh/retry behavior;
  • any adjacent critical flow.

If I rolled back, I verify the rollback restored the intended behavior rather than assuming the deployment platform handled everything perfectly.

Step 9: communicate facts, not guesses

If users are affected, I avoid pretending certainty I do not have.

A useful status message is factual.

For example:

Profile updates are temporarily unavailable while I fix an access-control issue. Existing public profiles remain available.

That is better than:

Everything is hacked.

or:

It will definitely be fixed in ten minutes.

Clear communication protects trust during uncertainty.

Step 10: write the incident down after it is calm

Once the system is stable, I document:

  • what happened;
  • impact;
  • root cause;
  • how it was contained;
  • final fix;
  • what would prevent recurrence.

This is where an embarrassing bug becomes engineering knowledge.

Maybe I add a test.

Maybe a database policy needs review before deployment.

Maybe a monitoring alert was missing.

Maybe a manual deployment step should become automated.

The goal is not to create a corporate incident report for a one-person project.

It is to make the same class of failure less likely.

Monitoring changes the experience

Without monitoring, a serious bug may exist until a user complains.

I want basic visibility into:

  • application errors;
  • failed critical requests;
  • unexpected status changes;
  • deployment failures;
  • provider webhook failures where relevant.

I do not need an enterprise monitoring stack for every side project.

I do need a way to know when the core workflow is unhealthy.

Backups are part of debugging confidence

Data bugs are more frightening when I have no recovery path.

For important databases, I want to understand the platform's backup options before I need them.

I also treat migrations carefully.

A migration that destroys or transforms production data should have more thought behind it than a CSS change.

Recovery planning makes me more willing to diagnose carefully instead of rushing from fear.

Being solo does not mean being chaotic

There is a myth that process is only for big teams.

A simple process helps more when I am alone because there is nobody else to slow me down when I am about to make a bad panic-driven change.

My incident order is:

  1. assess impact;
  2. contain;
  3. preserve evidence;
  4. describe the symptom;
  5. check recent changes;
  6. reproduce safely;
  7. identify the layer;
  8. make the smallest justified fix;
  9. verify;
  10. document and prevent recurrence.

I may move through those steps quickly.

I still want the order.

The hardest part of a serious bug is not always the code.

It is controlling the urge to do ten things at once.

When I slow the problem into evidence and layers, I usually make better decisions.

That is the kind of discipline I want behind anything I ask real users to depend on.

Post a Comment

Previous Post Next Post

Contact Form