Nobody’s agency fails on a Tuesday. It fails over about five months, in a series of small concessions that each seem reasonable at the time. The demo gets rescheduled. The estimate slips by a fortnight, then another. A feature ships that mostly works. You start explaining to your board why the timeline moved, and you find you’re using the agency’s words to do it.
By the time somebody calls us, the failure is usually obvious in hindsight and was invisible at the time. What follows is the pattern, in the order it tends to appear. None of these is proof of anything on its own. Three or more together, and something is wrong that a stern email won’t fix.
1. The demos stopped being live
Early on, someone shared their screen and clicked through the actual product. Now you get a slide deck, a recorded walkthrough, or a Figma prototype described as “the latest build”.
There’s almost always a reason, and the reason is almost never good. Either the build is too unstable to demo cold, or the thing you’re being shown doesn’t exist yet in the way the deck implies. A team that is confident in its work clicks around in the real thing and doesn’t mind when something takes a second to load.
What to do: ask for a live demo on a URL you can open yourself, on your own device, without them present. The response tells you more than the demo will.
2. You can’t get a straight answer about what’s done
Ask what percentage of the build is complete and you get a number. Ask which specific features are finished, tested, and deployed to a place you can see, and the answer becomes a paragraph.
Percentages are a comfort device. They compress a hundred unresolved questions into one reassuring figure, and they’re almost always computed from effort spent rather than outcomes delivered. “Eighty percent done” frequently means “we have spent eighty percent of the budget.”
What to do: stop asking for percentages. Ask for a list of features that are live, and a list that aren’t, and insist the boundary between them is a deployment rather than an opinion.
3. The team changed and nobody told you
The senior engineer who impressed you in the pitch is now “overseeing” the project. Standups are run by someone whose name you learned last week. Nobody announced this; you assembled it yourself from calendar invitations.
This is the most common failure in the industry and the hardest to challenge, because on paper nothing has changed — the contract still names the agency, not the people. But software is made by specific humans, and swapping them mid-build costs you every hour they spent understanding your problem.
What to do: ask who has written code in your repository in the last month. If they can’t answer immediately, ask for read access to the repository and look at the commit history yourself. You are entitled to it.
4. Everything is “nearly ready to test”
The build has been two weeks from a testable state for six weeks. Each conversation moves the boundary slightly and never crosses it.
This is usually a symptom of a specific technical problem: there is no working deployment pipeline, so nothing can be reliably put in front of you. The work may genuinely exist on someone’s laptop. It just can’t be assembled into something real without a day of manual effort nobody wants to spend, so it keeps not happening.
What to do: ask directly whether there is an automated deploy, and how long it takes to get a change from a developer’s machine into an environment you can open. If the answer is more than an hour, or involves a person’s name, you’ve found the bottleneck.
5. Bugs come back
You report something. It gets fixed. Three weeks later it returns, or its cousin appears somewhere adjacent. Nobody can quite say why.
This is the clearest technical signal on the list, and it means one thing: there are no meaningful automated tests. Every fix is a manual patch with no safety net, so each change has a real chance of breaking something that used to work. The codebase has entered the phase where it costs more to change than it did to write.
What to do: ask what test coverage exists on the critical paths — login, payment, the core action your product performs. Not a number; ask what happens automatically when someone changes the checkout code.
6. The tone has changed
Early emails were curious and specific. Recent ones are defensive, or use process language where they used to use plain language. Someone has started saying “as per our previous discussion”. Meetings have more people in them and less substance.
This is not a soft signal. When a delivery team knows it is behind, communication becomes protective before it becomes honest, and the protective phase can last months. You’ll often feel this shift before you can evidence it.
What to do: name it, once, plainly and without accusation. “I get the sense this is harder than we expected. I would rather know now.” A team that’s fundamentally fine will be relieved. A team in trouble will reassure you, and you’ll have learned something.
7. Nobody on your side could pick it up
The deepest signal, and the one that decides how bad the ending is. If this relationship stopped tomorrow, could anyone else continue the work? Is there documentation? Do you hold the repository, the cloud accounts, the deployment keys, the App Store account?
Agencies rarely engineer this dependency deliberately. It accumulates through ordinary neglect: documentation nobody had time to write, credentials that live in one person’s password manager, an architecture that exists entirely in the head of whoever built it.
What to do: find out today, while the relationship is still functional. Ask for a handover document, confirm the accounts are in your company’s name, and check you can actually log into them. The answer determines whether a future exit is a fortnight of work or a quarter.
What this adds up to
One of these is a bad month. Three is a pattern. Five and you are not managing a project any more, you are managing a story about a project.
The uncomfortable part is that recognising it early is worth far more than being right about it later. Almost everyone we talk to says a version of the same thing: I think I knew around March. The cost of acting in March versus acting in August is not a bit more money. It is usually the difference between a fixable codebase and a rebuild, because the technical debt keeps compounding while the conversation stays polite.
None of this necessarily means starting again. Most of the codebases we inherit are more salvageable than they feel from the inside — what they lack is not talent but ownership. But that judgement needs someone senior reading the actual code, not a status report.
If several of these landed, two things might help. The build check is ten questions and about two minutes, and it will tell you roughly where you sit. And if you want to know what happens next, we’ve written down how a rescue actually runs — audit first, always, because the honest answer sometimes turns out to be that less is broken than you feared.