This is why I love the bootstrapping stories here on HN.
Like one anecdote where they were building an "app" for automatic hotel reservations IIRC.
The "app" was a form that fed into a Google Sheet, where the founders themselves took the data and called the hotels.
When they got some income, they automated small bits of the process one by one.
Sometimes it's good to just have _something_ out there and see if there's a market for it before carefully crafting a beautiful piece of software nobody will ever use. It all depends on whether you're doing it to solve a problem for someone or for the process of writing code. Both are perfectly valid reasons.
It's totally fine to prototype, but you need to take care when you try to morph a prototype into a real product.
Very often people just take the shortest path from a to b, every single time. So you start with a reasonably shoddy prototype, but then you add some small feature, repeat 1000 times and now you still have a shoddy prototype but it's actually a pretty big project and it's all completely cursed because at no point did anyone do any actual software engineering. And of course now it's too big to rewrite or fix so the only way forward is to keep building on this completely broken mess.
At some point you need to scrap the prototype and replace it with something proper, or at least have a solid plan for how you're going to morph the prototype into something proper. This is often challenging and time consuming work, so a lot of developers tend to never really do it. They just execute the shortest path to get each new feature implemented over and over for years while number of bugs keeps increasing and velocity keeps decreasing because nothing makes sense, everything is more difficult than it should be etc.