We have already solved large areas of common classes of bugs at the language level, through strong static typing, memory safety and safe concurrency (Rust is the vanguard here but there are lots of languages that tackle these problems in effective ways).
Institutional inertia (technical debt) is the only reason why we can't apply these solutions to all software. I work on a PHP app with code that goes back 15 years. To convert it to rust we'd have to invest basically the same as the operating cost of the company. That'll never happen.
Once "safe" languages are used, there are still bugs of course. But what are those bugs? Failures of thought, plain and simple. Structural engineers work within the limits of physical reality and these constraints greatly limit the range of possible creation, thus also the range of possible failure.
Software has limits too, in memory, storage and processing capacity. But otherwise it works entirely in the realm of pure thought.
Well defined specifications that can be turned into concrete tests can solve a lot of these problems, too. (But this is also very expensive).
But even if you have specs and tests, there is no magic formula for ensuring your ideas are always sound. If the idea is wrong you can't even write tests to ensure it's correct. "Correctly" functioning components can have complex, difficult to predict side-effects when composed into complex systems.
We do have everything we need to write highly reliable software. But solving the software failure problem is the same task as solving the erroneous thinking problem. I don't know that we meat-sacks can "solve" that problem.