For btoa() you'd get TypeError instead of "InvalidCharacterError", but the conversion to bytes would happen in the IDL layer, which seems better?
The same is true for atob() which effectively returns a byte sequence that the IDL layer can then turn into a string to be exposed to JavaScript.
(The latter is also useful for an upcoming refactoring that allows us to reuse the atob() algorithm for data URLs.)