Search code examples
meteor

MeteorJS update failed: Access denied. No allow validators set on restricted collection for method 'update'


I have a legacy Meteor project with "Order" object and two methods like these:

  updateOrderStatus: function(props) {
    ...
    return Orders.update(
      {
        _id: props.orderInternalId
      },
      {
        $set: {
          statusHistory: statusHistory,
          status: props.status
        }
      }
    );    
  },

  checkOrderStatus: function(props) {
    ...
    // the update function call on both client and server
    var updateStatus = function(order) {
      newStatus = ...
      Orders.update(
        {
          _id: order._id
        },
        {
          $set: {
            status: newStatus
          }
        }
      );
    };

    if (Meteor.isClient) {
      // for client, must subscribe to the order and fulfill first, else will return
      Meteor.subscribe("orderByOrderId", { orderId: props.orderId }, function(
        err
      ) {
        if (err) return throwError(err);
        var order = Orders.findOne({
          orderId: props.orderId
        });
        updateStatus(order);
      });
    } else {
      var order = Orders.findOne({
        orderId: props.orderId
      });
      updateStatus(order);
    }
  }

When first method above is called, the function runs twice in both client and server. No errors. No issues.

When second method is called, it will throw this error on client:

update failed: Access denied. No allow validators set on restricted collection for method 'update'.

No issue on server. Updates to the order is saved correctly.

In fact we have seen this error message for months on production, it appears to be not affecting anything. Why is this error being thrown on client, just for the second method?

Note: This "Order" object has no allow/deny things defined.


Solution

  • You are updating in the subscribe callback. In the callback, you lose method context. In the client, you cannot update collection without method context.

    Why no effect on the production? Methods runs on both side. You've failed on the client then success on the server.

    Remove the client logic (if Meteor.isClient ... ). It's useless currently.

    This logic is for the optimistic ui. If you want to fix this problem, subscribe first then call the method.