Debug Ghosts, Part XI
The Mobile Page That Didn’t Need to Exist
It started, as these things often do, with a perfectly reasonable assumption.
Mobile editing was broken.
Not catastrophically broken. Not throwing errors. Just… unusable. The layout collapsed. The image upload worked inconsistently. And the content editor—powered by TinyMCE—felt like it had been designed for a different planet.
So I did what any rational developer would do.
I built a second path.
A mobile-only page. A simplified form. Hidden fields to satisfy validation. A special route:
/work/?mobile=1
No TinyMCE. No clutter. Just the essentials:
- Image
- Title
- Summary
- Menu
- Public
It worked.
On desktop, in mobile emulation, everything behaved. Stories saved. Images uploaded. The flow was clean. It felt like progress.
But then the ghosts arrived.
The First Disturbance
The mobile page worked locally.
On staging, it didn’t.
Same code. Same URL. Different result.
The page loaded, but it wasn’t the mobile template. No yellow debug blocks. No hidden fields. Just the old desktop form staring back, as if nothing had changed.
I checked the route.
I checked the query string.
I checked the deployment.
Eventually, I realized the truth.
I hadn’t deployed the changes.
The ghost wasn’t in the code.
It was in my environment.
The Second Disturbance
Once deployed, the mobile page appeared.
But something else was wrong.
Fields that should have been set weren’t.
blogstubbornly remained1family_iddisappeared entirely
Hidden inputs were added. Defaults were forced. Backend overrides were introduced.
Still, the data didn’t behave.
At this point, the system had grown more complex than the original problem.
Two templates.
Conditional routing.
Hidden fields compensating for missing ones.
Backend logic compensating for frontend assumptions.
The ghost was spreading.
The Accidental Clue
Then something unexpected happened.
While testing, the desktop form appeared again.
Not the mobile version.
The original work.html.
But this time, something was different.
The content field worked.
No TinyMCE toolbar.
No interference.
Just a plain textarea.
And it saved correctly.
On mobile.
The Realization
The problem was never the form.
It was never validation.
It was never routing.
It was never mobile support.
It was TinyMCE.
Once it wasn’t actively interfering, the original form worked everywhere.
The mobile page—the one built to solve the problem—was unnecessary.
The ghost wasn’t in the system.
It was in the assumption.
The Exorcism
No dramatic fix.
No rollback.
No rewrite.
Just a quiet change in perspective.
Keep one template.
Let TinyMCE load only when it behaves.
Let the textarea do its job everywhere else.
The second path disappeared.
Why This One Matters
This wasn’t a bug.
It was over-engineering in response to a misdiagnosed problem.
The instinct to isolate mobile was reasonable. The execution was careful. The result even worked.
But it wasn’t needed.
Every extra path adds weight:
- More templates
- More routing
- More edge cases
- More ghosts
Sometimes the fastest way forward is not building something new.
It’s removing the thing that’s in the way.
Ghost Survival Rule #11
Before building a second path, disable the thing haunting the first one.
A Calmer Ending Than It Began
In the end, nothing dramatic changed.
No new system.
No new architecture.
Just one form, doing what it was supposed to do all along.
And one fewer ghost in the codebase.
End of Part XI 👻
Posted in ghost-stories by TFOL BLOG