I think code generation can be useful if exactly one of these holds:
If the code may be regenerated but is also editable by humans, it immediately becomes a maintenance nightmare. Someone will have changed something in the resulting code, someone else changes something in the generation process, and you have a hard to find bug.
The resulting code can never be edited by a human.
This is perhaps the most useful case. Some examples:
Templates, macros, generics. Can be hard because especially the former lack type safety, and error messages may relate to the result instead of the transformation code. But very powerful.
Languages differ greatly in how they handle this (and whether they even use it at all, or use reflection instead, or nothing). See this question.
Ideally I'd want these to happen at compile time, with the resulting code never exposed to the programmer, because it shouldn't be changed.
The code will never be re-generated.
Here you generate code that you then edit and becomes part of the project.
This can be used to generate the structure and boilerplate of your project, that you then adapt. It can save some effort and help keep the code layout consistent. E.g. many frameworks come with a command to create an empty project.
Where possible, it's better not to need the boilerplate. But there'll be some, so this has a place.