Why can I not instantiate std::vector<std::unique_ptr<int>> with {std::move(first), std::move(second)}?

Why does the second solution work but not the first one?

List initialisation syntax that you use invokes the constructor that accepts a std::initializer_list. std::initializer_list is not movable though, and std::initializer_list<std::unique_ptr<T>> is not copiable, so invoking the constructor is not possible.

In the latter example you use the default constructor, so there is no problem.

Is there a workaround that would allow me to use the short and simple syntax with the initializer list?

You could list initialise an array, and use a pair of move iterators:

std::array arr{
    std::make_unique<int>(1),
    std::make_unique<int>(2),
};
return std::vector(
    std::make_move_iterator(std::begin(arr)),
    std::make_move_iterator(std::end(arr))
);

There was a proposal to make std::initializer_list movable, but it wasn't adopted (hasn't been adopted yet; who knows what future might bring).