In one sense this is of course true by definition, but in another sense I think it’s just a case of moving the goal posts around. The fact is the concept of an “error” indication is an item of information. Whether this information is represented as an out-of-band data value (e.g. -1), the presence/absence of an additional return value, or the transfer of control to another location in the program (pcall) seems to me more a matter of style. In other words “i have an error because a value/type is xxx” and “i have an error because i reached this line of code” are really just different ways to express the same thing. From that standpoint I don’t see error() as any more (or less) logically fundamental that an explicit error type or value representation; they are both ultimately conventionalized ways to indicate the same thing.
It is of course true that one style might be perceived as more convenient or elegant than another, but that is a matter of taste and is probably why people get so passionate about error handing methodologies.