code: function serializationError(msg, obj, fields) {
    var details = [];
    var i, l, field;
    for (i = 0, l = fields.length; i < l; i++) {
      field = fields[i];
      field.type.isValid(obj[field.name], {errorHook: errorHook});
    }
    var detailsStr = details
      .map(function (obj) {
        return f('%s = %j but expected %s', obj.path, obj.value, obj.type);
      })
      .join(', ');
    var err = new Error(f('%s (%s)', msg, detailsStr));
    err.details = details;
    return err;
  
    function errorHook(parts, any, type) {
      var strs = [];
      var i, l, part;
      for (i = 0, l = parts.length; i < l; i++) {
        part = parts[i];
        if (isNaN(part)) {
          strs.push('.' + part);
        } else {
          strs.push('[' + part + ']');
        }
      }
      details.push({
        path: field.name + strs.join(''),
        value: any,
        type: type
      });
    }
  }
docs: Provide a helpful error to identify why serialization failed.
  
  @param err {Error} The error to decorate.
  @param obj {...} The object containing fields to validated.
  @param fields {Array} Information about the fields to validate.