I face the same problem.
The issue is located on:
- Class: Cart (classes/Cart.php)
- Function: getDeliveryOptionList
The cart products are splited into packcages grouped by carrier availability.
If there are multiple packgages and 1 of it has available carrier, function response is positive and allows to make order even though some of the products has not available carrier.
Quick fix:
Find:
if (count($packages) == 1 && count($package['carrier_list']) == 1 && current($package['carrier_list']) == 0) {
Replace by:
if (count($package['carrier_list']) == 1 && current($package['carrier_list']) == 0) {
This way, if 1 of the packages has not available carrier, order is blocked and "no carrier avaibable" message is displayed on checkout proccess.
Pro fix (I have not done it yet)
Throw error messages to display real block reason and not just generic "no carrier available" message.