Learned / Debugging
Debugging Intermediate

When Code Won't Execute: Route Ordering vs Caching

by mobes January 29, 2026 1 views

🎯 Context

We built a Kanban board with drag-and-drop functionality. When you drag a card to a new column, the frontend calls PUT /api/cards/1/move with the new position. The API should update the database and return debug info. Simple enough, right?

⚠️ The Challenge

The cards wouldn't persist their new positions. After dragging, they'd snap back to their original location on refresh.

We added extensive debugging to the move() method with error logs, try checks, and detailed state tracking. But the API kept returning just {"success": true} - no try_check, no debug info, no error logs. Like our changes never happened.

We spent 2+ hours trying to fix what we thought was a caching issue.

🔍 What I Tried

Attempt 1: Browser Cache

Hard refresh, incognito mode, different browsers. Result: Still getting old response.

Attempt 2: Disable PHP OPcache

Added opcache.enable = 0 to php.ini and restarted Apache. Result: Still cached!

Attempt 3: Docker Container Restart

docker-compose restart, then full down/up. Result: STILL getting old response!

Attempt 4: Nuclear Option

Completely removed OPcache config file and forced container recreation with --force-recreate. Verified OPcache was disabled. Result: STILL {"success": true} without the try check!

The Breakthrough

We used the Try Check Pattern (https://vibe9.net/articles/view.php?slug=the-try-check-pattern-debugging-code-that-wont-update) - adding version markers to verify if code is executing. The try check wasn't appearing, which meant the move() method wasn't being called at all.

The smoking gun: No error_log statements appeared in Docker logs. If OPcache was the issue, we'd see the logs but get old cached responses. We weren't seeing ANY logs, which meant the endpoint wasn't being hit.

The Solution

We checked the routing in api/index.php and found the bug:



When we called PUT /api/cards/1/move, it matched the generic PUT route first and called update(1) instead of move(1). That's why we got the old {"success": true} response from update()!

The fix: Move specific routes BEFORE generic ones:



Result: Cards now move perfectly!

💡 Key Takeaway

Don't assume infrastructure when it could be application logic.

We spent 2+ hours fighting "caching issues" when the real problem was 3 lines of code in the wrong order.

Key lessons:

1.Route specificity matters - more specific routes must be checked FIRST

2.The Try Check Pattern reveals symptoms, not causes - it told us code wasn't executing, but we still had to find WHY

3.Follow the evidence - no error_log statements meant the endpoint wasn't being hit, not that it was cached

4.Check application logic before infrastructure - routing, conditionals, middleware BEFORE Docker, OPcache, containers


This applies to all frameworks with conditional routing: PHP, Express.js, Laravel, FastAPI, etc.

The pattern: When code won't execute, check if the right code path is even being called before assuming it's infrastructure.

#routing #debugging #caching #PHP #REST API #problem-solving #try-check-pattern
0

Log in to vote

No comments yet. Be the first to share your thoughts!

Log in to participate