Suppose an argument must be a non-negative integer. If the actual argument is not an integer, this is a type_error. If it is a negative integer, it is a domain_error.
Sadly, the must_be/2 predicate always throws ISO standard "type error" when its test fails, even when it is inappropriate. That should be configurable.
?- must_be(nonneg,-1). ERROR: Type error: `nonneg' expected, found `-1' (an integer)
That is unlikely to be a type error. The type is "integers". The domain is x >= 0.
A little diagram to discuss the "instantiation & type & domain verification pipeline". Note that instead of throwing, one may well consider just failing the predicate. Depending on the situation, that may make complete sense.