Submitted a raw tx that was already on the blockchain, to test it. I got 'missing inputs' instead of 'already exists'. Why?
Bitcoin Core has no idea which transactions already exist in the chain. It does not maintain a full index, because... it doesn't need to. In fact, when running in pruning mode, it doesn't even have the chain or its transactions at all.

The only thing it has is the set of unspent transaction outputs. Since you're trying to replay an existing transaction, all the inputs are already spent by its previous instance. As a result, the expected and correct response is that inputs are missing - i.e. your transaction is a double spend, and thus invalid.

I'd say that this is one of the advantages of the UTXO model: a replay and a double spend are one and the same, and there is no need to distinguish.