Technical debt tends to be talked about, and worried about, more by developers than by those running a business or looking after its finance. The problem is that not taking it into account will lead to bad decisions.
For a start, what is technical debt? It is a term coined by Ward Cunningham, the inventor of wikis, to think about the a problem by way of a metaphor with its financial counterpart. There is a page on the problem on the original wiki itself. It is an aspect of your system design (flaw is not always the right word) that will need to be fixed later.
It is a good way to think about the problem because technical debt is a future liability. The chances are that at some point it will have to be dealt with, and that will have to be paid for. It is very like a deferred liability or a simple debt: it results from a choice to pay later than pay now, it can cost more (akin to interest) than paying now, and it can be a perfectly reasonably choice, but if not kept under control can become a serious problem.
How does it arise? Some common ways are:
Because of a need to get something working soon, it is implemented in a quick but sloppy way.
A lack of skill or diligence on the part of a developer. For exmaple, it is very common to see application developers write good code but mess up database design. Another common problem is copy and paste programming when someone copies code they do not understand.
A lack of supervision or quality control.
An unanticipated change in requirements. This often leads to having to twist existing systems to do things that do not fit their design. A good programmer will instinctively feel that the code is ugly.
A system is not kept up to date with changes in components it uses. If a library changes in incompatible ways and you continue to write code the wrong way, you will have to fix it when you finally upgrade.
A lack of understanding of the design by programmers. Often caused when original programmers move on without leaving documentation.
Technical debt is inevitable. What matters is that it is well managed. Ward Cunningham says:
Shipping first-time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite. Objects make the cost of this transaction tolerable. The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object-oriented or otherwise.
The best advice is usually to fix the expensive (in terms of the debt metaphor, high interest) things first. Is a problem making current development more expensive? Is it going to cost a lot more to fix if you defer it? Will it cause other problems - for example is it a potential cause of bugs, or making it harder to fix bugs? Can you avoid making things worse?
A good current example of technical debt is code in Python 2. It will need to be upgraded to Python 3 at some point, preferably this year, because it will block most other updates. The problems are relatively easy to fix and the change can be partly automated, but there can be a lot of changes if you have a reasonable size code base and automated changes should be checked (mostly to remove unncessary changes). If you are not ready to bite the bullet yet, the minimum you should do to avoid making things work is ensure that all new code (or as near to all as possible all new code), including changes, is written to be compatible with both Python 2 and Python 3.
The first step to dealing with technical is to make sure you know about it. Ask developers what the current and potential problem areas are and what the potential problems are. Then you can cost and plan the fixes.