# Buggy code
def array_min(context, builder, sig, args):
    ty = sig.args[0].dtype
    if isinstance(ty, (types.NPDatetime, types.NPTimedelta)):
        # NaT is smaller than every other value, but it is
        # ignored as far as min() is concerned.
        nat = ty("NaT")

        def array_min_impl(arry):
            min_value = nat
            it = np.nditer(arry)
            for view in it:
                v = view.item()
                if v != nat:
                    min_value = v
                    break

            for view in it:
                v = view.item()
                if v != nat and v < min_value:
                    min_value = v
            return min_value

    else:

        def array_min_impl(arry):
            it = np.nditer(arry)
            for view in it:
                min_value = view.item()
                break

            for view in it:
                v = view.item()
                if v < min_value:
                    min_value = v
            return min_value

    res = context.compile_internal(builder, array_min_impl, sig, args)
    return impl_ret_borrowed(context, builder, sig.return_type, res)


# Traceback (ValueError)
In [324]: def test_0d_min(X):
...:     return np.min(X)
...:
...:

In [325]: test_0d_min(np.array([]))  # correct behavior
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
... (omitted)
ValueError: zero-size array to reduction operation minimum which has no identity

In [326]: nb.jit(test_0d_min)(np.array([]))  # incorrect
Out[326]: 0.0

In [328]: nb.jit(test_0d_min, parallel=True)(np.array([]))  # incorrect
Out[328]: 1.7976931348623157e+308

# Fixed code
def array_min(context, builder, sig, args):
    ty = sig.args[0].dtype
    if isinstance(ty, (types.NPDatetime, types.NPTimedelta)):
        # NaT is smaller than every other value, but it is
        # ignored as far as min() is concerned.
        nat = ty("NaT")

        def array_min_impl(arry):
            if arry.size == 0:
                raise ValueError(
                    (
                        "zero-size array to reduction operation "
                        "minimum which has no identity"
                    )
                )
            min_value = nat
            it = np.nditer(arry)
            for view in it:
                v = view.item()
                if v != nat:
                    min_value = v
                    break

            for view in it:
                v = view.item()
                if v != nat and v < min_value:
                    min_value = v
            return min_value

    else:

        def array_min_impl(arry):
            if arry.size == 0:
                raise ValueError(
                    (
                        "zero-size array to reduction operation "
                        "minimum which has no identity"
                    )
                )
            it = np.nditer(arry)
            for view in it:
                min_value = view.item()
                break

            for view in it:
                v = view.item()
                if v < min_value:
                    min_value = v
            return min_value

    res = context.compile_internal(builder, array_min_impl, sig, args)
    return impl_ret_borrowed(context, builder, sig.return_type, res)