Currently it is possible to stupidly lose mempool data by calling the rpc "savemempool" before the previous stored mempool has been read and processed to the memory mempool.

I haven't looked at the code yet, but at minimum one ugly solution would be to have a global g_is_mempool_read_finished (or something of the short) that starts false and gets sets to true once the reading is reading processing of mempool.dat is successfully finished. The rpc savemempool checks this global on the start and returns a an error while it remains false.

if (!fPruneMode)
        throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode.");
    LOCK(cs_main);
    int heightParam = request.params[0].get_int();
    if (heightParam < 0)
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height.");
    
    
    if (heightParam > 1000000000) {
        
        CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW);
        if (!pindex) {
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp.");
        }
        heightParam = pindex->nHeight;
    }
    unsigned int height = (unsigned int) heightParam;
    unsigned int chainHeight = (unsigned int) chainActive.Height();
    if (chainHeight < Params().PruneAfterHeight())
        throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning.");
    else if (height > chainHeight)
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height.");
    else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) {
        LogPrint(BCLog::RPC, "Attempt to prune blocks close to the tip.  Retaining the minimum number of blocks.");
        height = chainHeight - MIN_BLOCKS_TO_KEEP;
    }
    PruneBlockFilesManual(height);
    return uint64_t(height);
}
UniValue gettxoutsetinfo(const JSONRPCRequest& request)