How Do I Fix Bugs When There's Nobody Else to Ask?
Working as a solo developer means you'll spend a lot of time fixing problems that nobody else can see, and the fact is that learning to solve bugs on your own is less about having a perfect method and more about building up a kind of mental toolkit that works when there's nobody sitting next to you who can help. I've been building mobile apps for ten years now, and I can tell you that some of my worst Wednesday afternoon debugging sessions have taught me more than any formal training ever did, because when you're alone with a broken app and a deadline approaching, you learn to think differently about problems and their solutions.
The truth about solo debugging is that it's less about knowing everything and more about knowing where to look when you know nothing at all
Most bugs fall into patterns that you'll start recognising after you've fixed them a few times (took me about six months to realise this), and whilst every app is different, the way bugs behave and the way they hide from you tends to follow similar rules across different projects. Your job isn't to memorise every possible error, it's to get better at investigating them.
Understanding What Your Bug Actually Is
The first thing you need to do when something goes wrong is figure out what's broken compared to what you thought would happen, and this sounds simple but I've wasted entire mornings fixing the wrong problem because I assumed I knew what was broken without checking properly. Start by writing down exactly what you expected your app to do, then write down what it's doing instead, and the gap between these two things is where your bug lives.
Sometimes the bug you think you're seeing is just a symptom of something else breaking earlier in the code. I worked on a fintech app where users couldn't complete transactions, and I spent ages looking at the payment processing code before realising the session was timing out way before they even got to the payment screen.
Look at when the bug happens too, because timing tells you loads about what's going wrong. Does it happen on app launch? After a specific action? Only on certain devices? On a Thursday morning I discovered a healthcare app was crashing, but only for users in certain time zones, which led me to a date formatting problem I'd never have found otherwise.
Reading Error Messages Like a Map
Error messages are sort of like directions written by someone who knows where they're going but isn't great at explaining it to strangers, and the key is learning to spot the useful bits amongst all the technical noise that doesn't help you much. The last line of a stack trace usually tells you where the app actually crashed, whilst the lines above show you how it got there, and reading from bottom to top makes more sense than trying to understand the whole thing at once.
Copy the error message into a text file and highlight the parts that reference your own code rather than system libraries, because those are the bits you can change
Most error messages include a file name and a line number, which is your starting point for investigation. When you see something like "MainActivity.kt:247" or "PaymentService.swift:89" that's telling you exactly where to look first, and whilst the problem might have started somewhere else, that location is where things fell apart enough for the app to give up.
- Null pointer exceptions mean you're trying to use something that doesn't exist yet
- Index out of bounds means you're asking for item number seven in a list that only has five items
- Network errors might be connection problems or server issues or wrong API endpoints
- Memory warnings mean your app is using too much RAM and might get killed by the system
Some errors are misleading though (learned that the hard way), where the message points you in one direction but the real cause is somewhere completely different. I remember a retail app that kept throwing database errors, but the database was fine... the problem was we were trying to write to it whilst it was still being set up on first launch. When dealing with map-based apps that keep crashing, you'll often find the error messages point to GPS services when the real issue is memory management.
Building Your Own Safety Net With Testing
Writing tests feels like extra work when you're already busy building features, but tests are basically future you helping present you by catching problems before users see them. I didn't write proper tests for my first few apps (kind of regret that now), and I spent so much time fixing bugs that I'd already fixed once before but had broken again without noticing.
Unit tests check that individual pieces of code work correctly on their own, like testing that your price calculation function returns £4.99 when it should and not £499 by accident. Integration tests check that different parts of your app work together properly, like making sure that when someone adds an item to their basket, it shows up in the basket screen with the right price and product details. This becomes especially important when you're deciding which features are must-have versus nice-to-have, as your core functionality needs rock-solid testing.
| Test Type | What It Checks | When To Use It |
|---|---|---|
| Unit Test | Single function or method | For business logic and calculations |
| Integration Test | Multiple components together | For data flow between screens |
| UI Test | User interface behaviour | For critical user journeys |
| End-to-End Test | Complete user workflows | Before releasing updates |
You don't need to test everything, and I've found that focusing on the parts of your app that handle money or user data or complex calculations gives you the most value for your time. A simple e-commerce app needs solid tests around basket totals, discount codes and payment processing, because those are the bits where bugs cause real problems for your users and your business. Having a proper testing strategy also helps when planning for post-launch maintenance and updates.
When Your App Crashes and Nobody's Watching
Crash reporting tools are worth their weight in gold when you're working alone, because they tell you about problems happening to real users that you'd never discover through your own testing. I use Firebase Crashlytics on most projects now, and it's free, which helps when you're watching your budget carefully.
The crashes you don't see are often more common than the ones you do, because users experience your app in ways you never thought to test
Setting up crash reporting takes maybe thirty minutes, and then it runs quietly in the background collecting information whenever something goes wrong. You'll get reports that show you exactly which line of code crashed, what the user was doing beforehand, what device they were using, and how many other people have seen the same crash. This is particularly crucial when you're working on apps that need to work across different screen sizes, as device-specific crashes are common.
I worked on an education app that seemed fine during all my testing, but crash reports showed it was failing for users with older Android phones because they had less memory available. Without those reports I'd never have known, because I was testing on my own relatively new phone.
The pattern of crashes tells you how urgent they are too... if one user had one crash, it's probably worth noting but not panicking about, but if thirty per cent of your users are seeing the same crash within minutes of opening the app, you need to fix that pretty quickly before your ratings tank.
Finding Answers Without Asking People Directly
The Internet contains solutions to probably eighty per cent of the bugs you'll encounter, but finding those solutions requires being good at searching for them. I've got better at this over time (slowly, I guess), and the trick is describing your problem in a way that matches how other people have described similar problems before.
Stack Overflow has been around long enough that most common bugs have been discussed there, and when you find a question that matches your situation, read through all the answers not just the accepted one, because sometimes the second or third answer is more relevant to your specific case or uses a newer approach. This becomes even more important as development trends evolve with AI and new programming approaches.
- Search for your exact error message in quotes to find people who've seen the same thing
- Add your platform (iOS, Android, React Native) to narrow down results
- Include the library or framework name if your bug relates to specific code
- Try removing specific details like variable names to find more general solutions
GitHub issues on open source libraries are brilliant for finding bugs related to third-party code you're using, because other developers have often reported problems and the library maintainers have explained what's going wrong. I've solved so many odd behaviours by searching the issues list for the libraries I'm using.
Documentation is boring to read but surprisingly helpful when you're stuck (crazy when I think about it). The official docs for iOS and Android include example code that shows you the right way to use different features, and often the example code reveals what you're doing differently that's causing your bug. If you're working on smartwatch apps, the platform documentation becomes even more critical due to the unique constraints.
Keeping Track of What You've Already Tried
When you've been debugging for a couple of hours, your brain starts forgetting which solutions you've already attempted, and this leads to wasting time trying the same fix twice or accidentally undoing something that was working. I keep a simple text file open where I note down each thing I try and what happened, which sounds basic but has saved me loads of times.
Before you change anything, commit your working code to version control so you can get back to a known state if your fix makes things worse
Your notes don't need to be formal or detailed, just enough that you can look back and see what you did. Something like "tried moving the API call to viewDidLoad - still crashed" or "changed timeout to ten seconds - no difference" is plenty, and writing it down forces you to think about whether each attempt actually changed anything. This approach is especially valuable when working on apps that leverage new technologies where debugging patterns might not be well established yet.
| Time | What I Tried | Result |
|---|---|---|
| 2:15pm | Added null check before accessing user data | Didn't fix the crash |
| 2:40pm | Moved database init to earlier in launch | Still seeing the error |
| 3:10pm | Wrapped the whole thing in try-catch | Crash stopped but data not saving |
Version control becomes your safety net here, because you can try aggressive fixes knowing you can revert back if they don't work. I use Git for everything now, and I commit my code every time I have something that runs without crashing, even if it's not completely fixed yet.
Making Small Changes Instead of Big Guesses
When you're frustrated with a bug that won't die, there's a temptation to rewrite large chunks of code hoping that fixes it, but this usually makes things worse because now you don't know which change fixed the problem or introduced new problems. Change one thing at a time, test whether it helped, then move on to the next change if needed.
Small changes give you information about what's wrong even when they don't fix the bug. If you add a log statement and it never prints, you know that code isn't running at all, which narrows down where to look next. If you remove a feature and the crash stops, you know the bug lives somewhere in that feature. This methodical approach becomes crucial when dealing with interface elements that need careful positioning, where small changes can have big impacts on user experience.
I built an e-commerce app where the basket total was occasionally wrong by a few pence, and I wanted to rebuild the whole calculation system, but instead I added logging to each step of the calculation. Turned out we were rounding prices too early in the process, and the fix was changing one line rather than the hundred lines I almost rewrote.
Comment out suspicious code rather than deleting it straight away, because you might need to put it back or compare it against your new version. This has saved me a few times when my fix worked but broke something else, and I needed to look at what the old code was doing differently.
Knowing When to Start Over Versus Keep Fixing
Some bugs are symptoms of deeper problems with how you've structured your code, and sometimes starting fresh with a better approach takes less time than patching over a flawed design. This is a tough call to make when you're on your own, because there's nobody to tell you whether you're giving up too easily or stubbornly fixing something that's fundamentally broken.
The decision to rewrite comes down to whether you're fighting against your own code more than you're building with it
I generally consider rewriting when I've got multiple bugs in the same area of code, or when every fix creates a new problem somewhere else, or when the code has become so patched and complicated that I can't follow what it's doing anymore. A healthcare app I worked on had a data sync system that kept failing in different ways, and after two weeks of fixes I rebuilt it in three days using a cleaner architecture. When working on innovative automotive apps, you might find that cutting-edge requirements need completely fresh approaches rather than patches.
Before you rewrite anything major, make sure you understand why the current version is failing, because if you don't know what went wrong the first time, you'll probably make similar mistakes in the new version. Write down what the code needs to do, what problems the current version has, and how your new approach will avoid those problems.
Start small with rewrites... rebuild one screen or one feature rather than the entire app, and make sure your new version works before moving on to the next piece. I've seen developers (sort of including past me) decide to rebuild their whole app and then run out of energy halfway through, leaving them with an old broken version and a new unfinished version.
Conclusion
Debugging alone is partly technical skill and partly developing a patience with yourself and your code that lets you work through problems methodically instead of randomly. You'll get better at this the more bugs you fix, and each solved problem teaches you something about how to approach the next one, which means your early projects take longer to debug than your later ones do. The bugs never stop coming (they really don't), but you get faster at recognising them and more confident in your ability to fix them without needing someone else to tell you what's wrong, and that confidence is what makes solo development sustainable rather than just constantly stressful.
If you're working on an app and need someone to help untangle a tricky problem, or you want a second pair of eyes on something that's been bothering you for too long, get in touch and we can talk through what you're building.
Frequently Asked Questions
If you've spent more than a few days on the same bug and every fix creates new problems, it's worth considering a rewrite of that specific feature. The key indicator is when you're fighting against your code structure rather than just fixing a logical error.
Search for your exact error message in quotes, then add your platform (iOS/Android) and any relevant library names to narrow results. If that doesn't work, try removing specific details like variable names to find more general solutions that match your situation.
Focus your testing efforts on areas that handle money, user data, or complex calculations where bugs cause real problems. You don't need to test everything - prioritize the core functionality that would break your app or business if it failed.
Check your crash reporting data to see how many users are affected and how often it happens. If 30% of users see the same crash within minutes of opening your app, that's urgent. One user experiencing one crash is worth noting but not an emergency.
Write down exactly what you expected your app to do, then write what it's doing instead - the gap between these is your actual bug. Also pay attention to when the bug happens, as timing often reveals the real cause versus just symptoms.
Keep notes of what you've tried and the results, make one small change at a time, and always commit working code before attempting fixes. If you're repeating the same attempts or making large changes without understanding why, you need to step back and approach it more systematically.
Focus on the parts of the error message that reference your own code rather than system libraries, and remember that the crash location isn't always where the problem started. Look at what was happening before the crash occurred, especially with timing-related issues.
Share this
Subscribe To Our Learning Centre
You May Also Like
These Related Guides

How Do I Keep My App Working When Updates Break Things?

How Do You Test Your App Idea Without Building Anything?



