Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

document.save corrupts complex Map fields of the document (with additionnal $* keys) #15196

Closed
2 tasks done
lmontand opened this issue Jan 22, 2025 · 0 comments · Fixed by #15217
Closed
2 tasks done
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@lmontand
Copy link

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

8.9.5

Node.js version

22.13.1

MongoDB server version

8.0.4

Typescript version (if applicable)

No response

Description

After upgrading from mongoose 7.8.6 to mongoose 8.9.5, modifying a Map field containing an array corrupts the Map with invalid '$*' keys in the Map.
Once the Map is corrupted, it cannot be read or modified with mongoose anymore.
See example below to reproduce.

Note that we also quickly tested it with a mongoDB version 6 and 7; the problem is still the same. It seems to be only related to the version of mongoose.

Steps to Reproduce

In the example below. The field test_map if a map of an array of objects. It gets corrupted at step two of the code and we can observe this corruption at steps 3 and 4 of the code.

const mongoose = require('mongoose');

// Schema
const test_collection_schema = new mongoose.Schema({
    name: {type: String, required: true},
    test_map: {
        type: Map,
        of: [{
            num: {type: Number, required: true},
            bool: {type: Boolean, required: true}
        }]
    }
});

// Mongo relation
const Test_collection = mongoose.model('Test_collection', test_collection_schema, 'test_collection');

run_test().catch((err) => console.error(err));

async function run_test () {
    // 0. Create and save a new document
    let doc1 = new Test_collection({name: 'name1', test_map: new Map()});
    await doc1.save();
    console.log('log #0', doc1.test_map);
    
    // 1. Refresh the document from the db
    doc1 = await Test_collection.findOne({_id: doc1._id});
    console.log('log #1', doc1.test_map);
    
    // 2. Modify the document (add a new key in the test_map map)
    doc1.test_map.set('key1', []);
    await doc1.save();
    console.log('log #2', doc1.test_map);
    
    // 3. Now, the document is wrong in the db and we cannot access the test_map anymore.
    doc1 = await Test_collection.findOne({_id: doc1._id});
    console.log('log #3', doc1.test_map);

    // 4. If get the object with .lean, we see that there is a problem in the db.
    //    The map contains an additionnal key '$*', which should not be present.
    doc1 = await Test_collection.findOne({_id: doc1._id}).lean();
    console.log('log #4', doc1.test_map);
};

Below is the resulting stdout (with mongoose 8.9.5):

log #0 Map(0) {}
log #1 Map(0) {}
log #2 Map(1) { 'key1' => [] }
log #3 undefined
log #4 { '$*': { key1: [] }, key1: [] }

Expected Behavior

Here is the correct stdout that is expected (generated with mongoose 7.8.6):

log #0 Map(0) {}
log #1 Map(0) {}
log #2 Map(1) { 'key1' => [] }
log #3 Map(1) { 'key1' => [] }
log #4 { key1: [] }

In particular, we see that after step 2 of the code, the object is corrupted in the DB with an additional '$*' key in the Map. Such a key is not valid and makes further access to the map with mongoose fail.

@vkarpov15 vkarpov15 added this to the 8.9.6 milestone Jan 23, 2025
@vkarpov15 vkarpov15 added the has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue label Jan 23, 2025
@vkarpov15 vkarpov15 modified the milestones: 8.9.6, 8.9.7 Jan 31, 2025
@vkarpov15 vkarpov15 added confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue labels Feb 1, 2025
vkarpov15 added a commit that referenced this issue Feb 4, 2025
fix: avoid applying defaults on map embedded paths
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants