[Mongoose] How to Fix Error: Unable to invalidate a subdocument that has not been added to an array.

Tadashi Shigeoka ·  Sat, November 23, 2019

I’ll introduce how to investigate when you encounter the error “Error: Unable to invalidate a subdocument that has not been added to an array.” in Mongoose.

mongoose | マングース

Conclusion: Invalid Value in type: ObjectId Field

To start with the conclusion, it appears the error occurred when trying to save an invalid value that wasn’t in ObjectId format to a field defined as type: ObjectId.

Mongoose Error Message

Error: Unable to invalidate a subdocument that has not been added to an array.

Prerequisites: Mongoose Schema and Query

'use strict';
const { Schema } = require('mongoose');
const { ObjectId } = Schema;

const RegiTransaction = new Schema(
  {
    transactionHead: {
      type: Schema.Types.Mixed
    },

    details: [
      {
        transactionDetail: {
          type: Schema.Types.Mixed
        },

        sku: {
          type: ObjectId,
          ref: 'Sku'
        }
      }
    ]
  }
);

Executing the following update query resulted in “Error: Unable to invalidate a subdocument that has not been added to an array.”

const data = {
  details: [
    {
      transactionDetail: {
        foo: 'bar'
      },
      sku: 'Invalid ObjectId'
    }
  ]
};

await RegiTransaction.update(
  {
    _id: targetId
  },
  {
    $set: data
  },
  {
    upsert: true
  }
);

Solution: Validate ObjectId Before Issuing Update Query

As a solution, you can add validation processing before executing the update query to verify that the value to be saved in RegiTransaction.details.sku is in ObjectId format, allowing you to handle errors proactively without causing Mongoose errors.

That’s all from the Gemba.