That's a very valid point. So I think we have these two types of metaprogramming, the runtime type and the compile time type. The latter is compatible with static typing but the former clearly is not.
If the compiler is part of the runtime (i.e. an interpreter that compiles expressions in order to evaluate them), and then the type checker is part of the compiler, even eval should be able to throw type errors. What, then, is the problem?
It depends on what you mean by "runtime." If you're creating a new datatype, is that really "at runtime," or are you just talking to the compiler interactively?
To put it another way: metaprogramming might have effects at runtime, but not the kind of effects that change depending on what the runtime does. Metaprogramming should be deterministic for your program to be considered to be "in production."