Skip to content

storeSubdocValidationError ignored in update operations #9172

@itayl2

Description

@itayl2

Do you want to request a feature or report a bug?
bug

What is the current behavior?
Update operations (tested findOneAndUpdate & updateOne) store sub doc validation errors regardless of submitted options (storeSubdocValidationError:false), while .save() handles it properly.

If the current behavior is a bug, please provide the steps to reproduce.
See script:

const mongoose = require('mongoose');

const schemaOpts = {storeSubdocValidationError: false};
const innerSchema = mongoose.Schema({
    name: {
        type: String,
        required: [true, 'Missing']
    },
    val: {
        type: mongoose.Schema.Types.Mixed,
        required: [true, 'Missing']
    }
}, schemaOpts);

const fieldSchema = mongoose.Schema({
    subFieldName: {
        type: [innerSchema]
    }
}, schemaOpts);

const parentSchema = mongoose.Schema({
    parentFieldName: {
        type: fieldSchema
    }
}, schemaOpts);

const templates = {
    INVALID: {
        parentFieldName:
            {
                subFieldName: [
                    {}
                ]
            }
    },
    VALID: {
        parentFieldName:
            {
                subFieldName: [
                    {
                        name: 'testName',
                        val: 'testVal'
                    }
                ]
            }
    }
};

const main = async () => {
    const connectionString = % YOUR CONNECTION STRING %;
    const connOpts = {
        % YOUR CONNECTION OPTIONS %
    };
    console.log('Connecting...');
    const db = await mongoose.createConnection(connectionString, connOpts);

    const modelName = % YOUR MODEL NAME %;
    const Parent = db.model(modelName, parentSchema, modelName);

    console.log('Creating...');
    let doc;
    try {
        doc = await new Parent(templates.INVALID).save();
    } catch (err) {
        const found = Object.keys(err.errors);
        console.error(`Bad fields when creating (${found.length}): ${found}`);
	//Output: Bad fields when creating (2): parentFieldName.subFieldName.0.val,parentFieldName.subFieldName.0.name
    }

    doc = await new Parent(templates.VALID).save();
    console.log('Updating...');
    try {
        const updateResult = await Parent.findOneAndUpdate({_id: doc._id}, {$set: templates.INVALID}, {new: true, runValidators: true, fields: {_id: 0}, context: 'query'}).exec();
    } catch (err) {
        const found = Object.keys(err.errors);
        console.error(`Bad fields when updating (${found.length}): ${found}`);
	//Output: Bad fields when updating (3): parentFieldName.subFieldName.0.val,parentFieldName.subFieldName.0.name,parentFieldName
    }

    console.log('Done');
};

main();

What is the expected behavior?
Mongoose should only return return unique validation errors rather than one for the sub doc and one for the doc.

When debugging the src it seems like the issue is associated with the fact in lib/document.js #validatePath(), schemaType is of the actual field it's currently validating (i.e "name" / "val" in the attached example).
When using .save(), the schemaType is of the 'parentFieldName' which can then use the storeSubdocValidationError option.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
Mongoose: 5.9.20
NodeJS 12.13.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugWe've confirmed this is a bug in Mongoose and will fix it.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions