It isn't even the API vendors' fault necessarily.
Compared to HTTP/TCP/IP, abstractions between layers of the BLE stack are extremely leaky. Examples: indicating choice of PHY coding and channels in the equivalent of a `listen/connect` call, or the three different but intertwined places where fragmentation/reassembly can happen. Being effective with BLE requires deep understanding of the entire stack, and since it is difficult for a single person to have such level of understanding, we get bugs. By comparison, being effective with HTTP does not require one to know anything about the PHY layer, or TCP stream reassembly.
I suspect this is due to not having enough independent implementations of each layer - Bluetooth is designed and standardized by one committee, and the entire stack usually implemented as a single "thing", making it too easy to break abstraction when a new feature needs to be added.