[Mongoose] Error: Unable to invalidate a subdocument that has not been added to an array. の解決方法
Mongoose で Error: Unable to invalidate a subdocument that has not been added to an array. が発生したときの調査方法をご紹介します。
まず、結論から書いておくと type: ObjectId と定義している field に ObjectId 形式ではない不正な値を保存しようとしてエラーが発生していたようでした。
Mongoose エラーメッセージ
Error: Unable to invalidate a subdocument that has not been added to an array.
'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'
}
}
]
}
);
以下のような update クエリを実行すると Error: Unable to invalidate a subdocument that has not been added to an array. が発生しました。
cost data = {
details: [
{
transactionDetail: {
foo: 'bar'
},
sku: 'Invalid ObjectId'
}
]
};
await RegiTransaction.update(
{
_id: targetId
},
{
$set: data
},
{
upsert: true
}
);
対策案として update クエリを実行する前に、RegiTransaction.details.sku に保存される予定の値が ObjectId 形式であることを検証する validation 処理を追加することで Mongoose エラーを起こさずに未然にエラーハンドリングできます。
以上、Mongoose で Error: Unable to invalidate a subdocument that has not been added to an array. を調査・解決した、現場からお送りしました。