I worked on a Big oil company IT project that had failed twice due to bad code. As the business guy I figured out that the system would round round down the final non zero digit of any value stored in the system to either zero or five. Usually this would make the report numbers slightly off, but sometimes it could be massive. Say you bought 1,000 $9.00 parts the system would show $5,000 in cost instead of $9,000, but if you paid $9.26 for the parts it would show $9,250 in cost.
The root cause of this error was the IT team had one guy who was crazy smart and had a bucketfull of assumptions about what the problem was that couldn't imagine that the issue was one baked into some of the first code he had written.
In a nutshell, this was a reporting package that sat ontop of SAP that was supposed to be actually useable by field managers and guys who turned wrenches so they could keep track of their budgets and spending. Of course this was needed because SAP had been implemented with very little training and no helpdesk for users.
The project had been rolled out twice to the field and just rejected flat out because the numbers didn't match, million had been spent building it and there was a 3rd try before the entire system was scrapped and a few million spent on an off the shelf piece of software.
It took a while to find the root cause of the totals being off because I'd always get these great complex explinations as to why the data was off an they had project change orders in to fix it. Finally I just pulled data to find out what was going on, and saw this weird pattern of the data being off in specific places but it took a day before I had the insight that the same thing was changing $140.00 into $100.00 as $0.79 into $0.75 i.e. the final nonzero digit of any stored value was being rounded down to the either 0 or 5.
It is a good little business but failed because of bad management decisions and poorly built software.
Contact me if you want more details.
Outsourcing, high turnover, constantly changing requirements with unreasonable schedules all can lead to codebases that become too expensive to iterate on when the market demands more. Sometimes the only way out is to approach a complete rewrite which is usually a risky proposition.
Many times poorly coded products from the outside can have correlated symptoms of poor performance, bugginess, and slow feature development which are the cited reasons users may abandon the product.
TDD and also code analysis tools can help highlight what you actually need and what you don't.
The converse is true too, if you under-engineer you run the risk of not easily being able to scale up to new requirements.
Over-engineering creates an albatross where you'll fall under your own weight (too much code, slows down development, possibly bad performance, harder to debug). Under-engineering creates a house of cards that is fragile (more buggy, code gets duplicated and patched on, frustrating to work on, hard to refactor).
Poor code leads to technical debt, startup or not. Like all debts, if you don't bite the bullet and repay it, you will eventually be consumed by it.
You can fix the code after you launch, or you can just never launch.