How to fix error "Exception while invoking method 'actionFail' Error: When the validation object contains mongo operators, you must set the modifier option to true"

collection

import SimpleSchema from 'simpl-schema';
ActionLogsFail = new Mongo.Collection('actionLogsFail');
let SchemaActionLogFail = new SimpleSchema({
    "module":{
        type:String,
        index:true,
        optional: true,
        label:"Module Name"
    },
    "action":{
        type:String,
        index:true,
        optional: true,
        label:"Action Name"
    },
    "created_at":{
        type: Date,
        optional: true,
        label: "Date Create added by system",
        autoValue: function() {
            if ( this.isInsert ) {
                return new Date;
            }
        }
    },
    "ip_address":{
        type: String,
        label: "IP Address",
        optional: true,
    },
    "detail":{
        type: Object,
        label: "Detail",
        optional: true,
        blackbox: true
    }
});
ActionLogsFail.attachSchema(SchemaActionLogFail);

export default ActionLogsFail;

Methods

Meteor.methods({
'actionFail'(module,action,detail)
    {
        var ip = this.connection.clientAddress;
        ActionLogsFail.insert({
            module:module,
            action:action,
            detail:detail,
            ip_address:ip,
            created_at:new Date()
        });
    },
})

insert Data

{
 module: 'Authentication',
 action: 'Fail',
 ip_address: '127.0.0.1',
 created_at: 2020-06-13T06:49:11.037Z,
 detail: {
  email: 'test@test.com',
   err: {
     isClientSafe: true,
     error: 403,
     reason: 'Incorrect password',
     message: 'Incorrect password [403]',
     errorType: 'Meteor.Error'
   }
 }

Display Error

Exception while invoking method 'actionFail' Error: When the validation object contains mongo operators, you must set the modifier option to true
I20200613-13:49:11.165(7)?     at doValidation (/project/node_modules/simpl-schema/dist/doValidation.js:64:11)
I20200613-13:49:11.165(7)?     at ValidationContext.validate (/project/node_modules/simpl-schema/dist/ValidationContext.js:153:56)
I20200613-13:49:11.165(7)?     at doValidate (packages/aldeed:collection2/collection2.js:426:33)
I20200613-13:49:11.165(7)?     at Collection.Mongo.Collection.<computed> [as insert] (packages/aldeed:collection2/collection2.js:196:14)

Thank you.

Collection2 uses SimpleSchema under the hood. SimpleSchema requires you to have modifier: true in your validation options if the object you are checking contains a MongoDB modifier https://github.com/aldeed/simpl-schema/blob/master/README.md#validate-a-mongodb-modifier.

Now, I can’t see anywhere in your sample insert data something that resembles a MongoDB modifier. However, I would double check if in reality that object is clean when inserting. You can try to stringify & parse it, or use SimpleSchema for that: https://github.com/aldeed/simpl-schema/blob/master/README.md#automatically-clean-the-object-before-validating-it

1 Like

@illustreets Thank you.

Hi @illustreets ,

I’m having the same error and wonder if you could tell me what modifier: true in your validation options means

Could you show me a example how to set modifier: true ?
Would that be inside of SimpleSchema?

Thank you

Hi @miki11,

It’s right there, in my reply. There is a link to the documentation of SimpleSchema on GitHub, more specifically to this snippet:

import SimpleSchema from "simpl-schema";

const validationContext = new SimpleSchema({
  name: String,
}).newContext();

validationContext.validate(
  {
    $set: {
      name: 2,
    },
  },
  { modifier: true }
);

console.log(validationContext.isValid());
console.log(validationContext.validationErrors());

That $set key designates a MongoDB modifier. Because of that one, SimpleSchema would complain, so you have to specify in the options { modifier: true }. But maybe you don’t have a Mongo modifier, and there is some other key that starts with $ in your object. It would be helpful if you posted the object in question and the schema you use for validation.

1 Like

@illustreets thanks your answer!

I also use $set and the below are how my code look like.

   modifyQuestion(question, frequency) {
    check(question, Object);
    check(frequency, String);
    const checkExistingQuestion = Measures.findOne({questionId: question._id});
    if (checkExistingQuestion) {
      Measures.update(
        {questionId: question._id},
        {
          $set: {
            title: question.text,
            type:
              question.type === questionType
                ? MeasureType.sample1
                : MeasureType.sample2,
          },
        },
      );
    } else {
      console.log('else');
      Measures.insert(
        {
          $set: {
            title: question.text,
            type:
              question.type === questionType
                ? MeasureType.sample1
                : MeasureType.sample2,
          },
        },
      );
    }
  },
Measures.attachSchema(
  new SimpleSchema({
  title: {
      type: String,
      label: 'Title',
      min: 3,
    },
    type: {
      type: String,
      label: 'Measure Type',
      allowedValues: [
        MeasureType.sample1,
        MeasureType.sample2,
        MeasureType.sample3,
      ],
    },
})
)

So this case, just need to add { modifier: true } like this? or am I getting wrong?

   modifyQuestion(question, frequency) {
    check(question, Object);
    check(frequency, String);
    const checkExistingQuestion = Measures.findOne({questionId: question._id});
    if (checkExistingQuestion) {
      Measures.update(
        {questionId: question._id},
        {
          $set: {
            title: question.text,
            type:
              question.type === questionType
                ? MeasureType.sample1
                : MeasureType.sample2,
          },
        },
        {modifier: true}
      );
    }
  },

I am not sure whether you can specify the modifier option when attaching a schema to a collection, I haven’t checked that. I know you can pass it to the SimpleSchema.validate method.

That being said, in your code above, I can spot that the following code will likely cause you trouble:

Measures.insert(
    {
      $set: {
        title: question.text,
        type:
          question.type === questionType
            ? MeasureType.sample1
            : MeasureType.sample2,
      },
    },
  );

You are trying to insert a document containing a MongoDB modifier, which is most likely not something you want to do. That should be:

  Measures.insert({
    title: question.text,
    type:
      question.type === questionType
        ? MeasureType.sample1
        : MeasureType.sample2,
  });

In my reply to the original poster, I was saying that

But it looks to me that, in your case, this may be the actual problem.

1 Like

As you suggested insert didn’t work because of $set

Thank you very much!