Debugging
The Bug Wasn't in the Component
An inventory issue that changed where I look before changing frontend code.
The Bug Wasn't in the Component
An inventory issue that changed where I look before changing frontend code.
I was working on an inventory-related feature in an e-commerce application. Part of the requirement was straightforward: whether the available stock quantity appeared on the product page depended on a configuration setting, along with a few product-level conditions.
I implemented the change, tested the different scenarios locally, and everything behaved the way I expected.
Then the same feature was tested in another environment.
The configuration was disabled, but the stock quantity was still showing.
My first thought was predictable: I must have missed something in the frontend.
It looked like a frontend bug
The quantity was visible on the product page, so I went back to the component responsible for displaying it.
I checked the rendering condition again, then the values involved in that condition, and finally the different product scenarios the component needed to handle.
Nothing immediately explained what I was seeing.
More importantly, I couldn't find enough evidence to justify changing the rendering logic.
I could have added another condition to make the quantity disappear in that particular scenario. It would have been a small change, and visually it might even have appeared to solve the problem.
But that didn't sit right.
If the existing condition was behaving consistently with the information reaching it, another condition would only hide the behaviour. It wouldn't explain why the application had reached that state in the first place.
So instead of changing the component, I started looking at what was reaching it.
The component stopped looking like the problem
At that point, the question changed from:
“Why is this component showing the quantity?”
to:
“Why does this component believe the quantity should be shown?”
The difference is subtle, but it changed the direction of the investigation.
I started tracing the values involved in the decision.
Was the application receiving the configuration I expected?
Was the behaviour consistent after that configuration changed?
Was the same state being reflected in this environment as in my local setup?
As I worked backwards through the flow, changing the component started to make less sense.
There was another clue: the behaviour didn't always appear to reflect configuration changes immediately.
That pushed the investigation beyond the rendering logic. If the environment wasn't consistently reflecting the state we expected, then things happening between configuration and rendering—including caching—were worth investigating further.
I don't want to make the story cleaner than it actually was and say, “we found the cache, cleared it, and the mystery was solved.”
That wasn't the conclusion I had at that point.
What I did know was that I no longer had enough evidence to call it a component bug.
And that distinction mattered.
So I followed the value instead
Before this, I often approached frontend debugging from the place where the problem became visible.
Something is wrong with a button? Start with the button.
A price looks incorrect? Start with the price component.
Stock information shouldn't be visible? Start with the condition responsible for rendering it.
There is nothing wrong with starting there. I still do.
What changed for me was assuming that the investigation should also end there.
In this case, what appeared on the screen was the result of a longer flow:
Configuration
↓
Application / API data
↓
State / environment
↓
Rendering logic
↓
What the user seesThat's deliberately simplified, but it captures the part I had initially overlooked.
The component was at the end of the chain. By the time something appeared on the screen, several decisions had already influenced what the component received.
That led me to a question I still find useful:
Is the component producing the wrong result from correct information, or is it producing the expected result from information that isn't what I expected?
Those two situations can look almost identical in the browser, but they lead to very different investigations.
If the first is true, the rendering logic becomes a legitimate place to investigate further.
If the second is true, adding another frontend condition may only make the underlying problem harder to see.
What changed in the way I debug
The useful part of this experience wasn't inventory or caching specifically.
It was realizing how easily the location of a symptom can influence where we expect to find its cause.
Now, when something works locally but behaves differently in another environment, I treat that difference as information rather than immediately assuming the implementation needs another condition.
I want to know what's different.
Is the application receiving the same data?
Is the expected configuration actually being reflected?
Could something between the configuration and the UI be influencing what I'm seeing?
Sometimes that investigation still brings me back to the component. A bad condition is still a bad condition.
But sometimes it doesn't.
And I've become more comfortable with not changing code until I understand which of those situations I'm dealing with.
I still start close to where a problem appears.
I just no longer assume I'll finish there.
Written by
Tanvir Sheikh
Software Engineer · Product Builder
I build and ship production-ready digital products and write about the engineering lessons behind them.
