To be clear, strncpy does not guarantee NUL termination. It takes a C string as the source argument, but it doesn't write out a C string; it writes out a very esoteric data structure that is unfortunately easily confused with a C string.
By contrast, strlcpy was intended to be a safer string copy routine: https://www.usenix.org/legacy/event/usenix99/full_papers/mil... In particular, it was designed to be what people seem think strncpy is. Its return value semantics are controversial, though mostly only among the glibc crowd as every other Unix libc, including musl and Solaris, now provide it. But the semantics were designed based on experience in fixing old C code, and observations about how developers tend to write C code, not based on prescriptive theories about how people should manipulate C strings in C code.
As you say, it does in fact obviate some errors. A value judgement as to which behaviors are more or less safe may be subjective, but the intent is not.