Read the error message
Seriously. Most developers skim error messages and jump to Stack Overflow. The error message is almost always telling you exactly what's wrong.
Rubber duck debugging works
Explaining the problem out loud forces you to articulate your assumptions. Half the time, the act of explanation reveals the bug. This connects to My Development Philosophy — simplicity makes debugging easier.
Binary search your way to the bug
Comment out half the code. Does the bug still happen? If yes, it's in the remaining half. Repeat. This is O(log n) debugging and it's embarrassingly effective.
Check your assumptions
The bug is never where you think it is. It's in the code you're "sure" works. Question every assumption, especially around state management, async timing, and cache invalidation.
Log strategically
console.log debugging is fine. But log at the boundaries — function entry/exit, API calls, state transitions. See Tools I Can't Live Without for the observability stack I use in production.