this behavior is intended
The intention was fine but it needs to be relaxed to support this situation.
a kind of transactional control
Without a database? Nothing in Jenkins is atomic.
It makes no sense to restart a step that already published the results.
It does, because the whole stage (or whatever block includes agent provisioning, source code checkout, build, and publishing) is retried when there is an infrastructure failure. In most cases the failure occurs earlier before recordIssues runs, but when multiple publishing-type steps are run it can happen that the agent fails after recordIssues has been run but while other steps are running. When the block is restarted, we expect everything to run again.
(At least for continuous integration and similar projects. If your project definition includes some sort of step which is inherently not idempotent, like deploying an artifact to a system which cannot handle repeated uploads, then you would just not be able to opt in to this retry system.)
Actually this behavior is intended to avoid that people use the same ID twice and overwrite their results.
Shouldn't Jenkins core provide a kind of transactional control that prevents such problems for plugins? It makes no sense to restart a step that already published the results.