encodeErrorCommon = (err, encodeRecur) => {
      const message = encodeRecur(`${err.message}`);
      assert.typeof(message, 'string');
      const name = encodeRecur(`${err.name}`);
      assert.typeof(name, 'string');
      // TODO Must encode `cause`, `errors`, but
      // only once all possible counterparty decoders are tolerant of
      // receiving them.
      if (errorTagging === 'on') {
        // We deliberately do not share the stack, but it would
        // be useful to log the stack locally so someone who has
        // privileged access to the throwing Vat can correlate
        // the problem with the remote Vat that gets this
        // summary. If we do that, we could allocate some random
        // identifier and include it in the message, to help
        // with the correlation.
        const errorId = encodeRecur(nextErrorId());
        assert.typeof(errorId, 'string');
        annotateError(err, X`Sent as ${errorId}`);
        marshalSaveError(err);
        return harden({ errorId, message, name });
      } else {
        return harden({ message, name });
      }
    }
Even if an Error is not actually passable, we'd rather send
it anyway because the diagnostic info carried by the error
is more valuable than diagnosing why the error isn't
passable. See comments in isErrorLike.

@param {Error} err
@param {(p: Passable) => unknown} encodeRecur
@returns {{errorId?: string, message: string, name: string}}