I discovered a race condition in sendrawtransaction. For details: see my comment in https://github.com/bitcoin/bitcoin/commit/1d46fe3327f6645fd79b442cd72ef422418c1a50.

If you send a raw transaction which has already been broadcasted, then you don't know whether you'll receive an RPC_TRANSACTION_ALREADY_IN_CHAIN exception, since you don't know whether a new block has just been received, which includes the transaction. There are use cases where such RPC_TRANSACTION_ALREADY_IN_CHAIN occurrences do not indicate an error; however, since this type of occurrence is very rare, developers are not likely to be aware of the possibility, and silence the exception. As a result, applications can potentially experience hard-to-diagnose, very rare errors.

I think the core of the problem is that sendrawtransaction tries to combine two use cases:
A: publish a transaction on the Bitcoin network
B: re-transmit an already known transaction to peers
RPC_TRANSACTION_ALREADY_IN_CHAIN might make sense for B, but for A (which is, IMHO, the primary use case) it is confusing.

}},
                        }},
                        {RPCResult::Type::STR_AMOUNT, "fee",  true, "The transaction fee paid if all UTXOs slots in the PSBT have been filled."},
                    }
                },
                RPCExamples{
                    HelpExampleCli("decodepsbt", "\"psbt\"")
                },
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
    RPCTypeCheck(request.params, {UniValue::VSTR});
    
    PartiallySignedTransaction psbtx;
    std::string error;
    if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
    }
    UniValue result(UniValue::VOBJ);
    
    UniValue tx_univ(UniValue::VOBJ);
    TxToUniv(CTransaction(*psbtx.tx), uint256(), tx_univ, false);
    result.pushKV("tx", tx_univ);
    
    UniValue unknowns(UniValue::VOBJ);
    for (auto entry : psbtx.unknown) {
        unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
    }
    result.pushKV("unknown", unknowns);
    
    CAmount total_in = 0;