{"record":{"id":"def22fed412612e8","repo":"Automattic/mongoose","slug":"cast-to-buffer-failed-for-value-value-type","errorCode":null,"errorMessage":"Cast to Buffer failed for value \"${value}\" (type ${valueType}) at path \"${path}\"","messagePattern":"Cast to Buffer failed for value \"(.+?)\" \\(type (.+?)\\) at path \"(.+?)\"","errorType":"exception","errorClass":"CastError","httpStatus":null,"severity":"error","filePath":"lib/schema/buffer.js","lineNumber":165,"sourceCode":"  if (SchemaType._isRef(this, value, doc, init)) {\n    if (value?.isMongooseBuffer) {\n      return value;\n    }\n\n    if (Buffer.isBuffer(value)) {\n      if (!value?.isMongooseBuffer) {\n        value = new MongooseBuffer(value, [this.path, doc]);\n        if (this.options.subtype != null) {\n          value._subtype = this.options.subtype;\n        }\n      }\n      return value;\n    }\n\n    if (value instanceof Binary) {\n      ret = new MongooseBuffer(value.value(true), [this.path, doc]);\n      if (typeof value.sub_type !== 'number') {\n        throw new CastError('Buffer', value, this.path, null, this);\n      }\n      ret._subtype = value.sub_type;\n      return ret;\n    }\n\n    if (value == null || utils.isNonBuiltinObject(value)) {\n      return this._castRef(value, doc, init, options);\n    }\n  }\n\n  // documents\n  if (value?._id) {\n    value = value._id;\n  }\n\n  if (value?.isMongooseBuffer) {\n    return value;\n  }","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/schema/buffer.js#L147-L183","documentation":"When casting a value that looks like a BSON Binary, mongoose copies its bytes and subtype; a Binary whose sub_type is not a number means the object is malformed or comes from an incompatible BSON implementation, so it is rejected as CastError Buffer instead of producing a corrupt Buffer.","triggerScenarios":"Passing a hand-built Binary-like object ({ value() {...}, sub_type: undefined }); two different bson package copies so the value duck-types into the Binary branch with a mismatched shape; bson major upgrades renaming sub_type to subType while mongoose/driver versions lag.","commonSituations":"Duplicate bson versions from dependency drift (npm ls bson showing several); mixing MongoDB driver versions with an older mongoose; test doubles imitating BSON Binary.","solutions":["Pass Buffer, Uint8Array, or plain strings to Buffer paths - mongoose converts them itself.","Deduplicate BSON: ensure a single bson/mongodb driver version (npm dedupe / resolutions) and a mongoose version compatible with it.","If constructing Binary manually, use the driver BSON class so sub_type is a number: new mongodb.Binary(buf, 0)."],"exampleFix":"// before\nconst fake = { value: () => buf, sub_type: undefined };\ndoc.data = fake; // CastError Buffer\n\n// after\ndoc.data = Buffer.from(buf); // or new mongodb.Binary(buf, mongodb.Binary.SUBTYPE_DEFAULT)","handlingStrategy":"validation","validationCode":"const isSafeBufferInput = (v) =>\n  v == null || Buffer.isBuffer(v) || v instanceof Uint8Array || typeof v === 'string';\n// before assigning a Binary, force a native type:\ndoc.data = isSafeBufferInput(v) ? v : Buffer.from(v.value(true));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run npm ls bson in CI and fail when multiple versions appear.","Upgrade mongoose and the MongoDB driver together as a locked pair; check their compatibility matrix.","Construct Binary values only via the driver BSON class, never hand-rolled duck-typed objects."],"tags":["cast-error","buffer","bson","driver-compat"],"backgroundTag":"mongoose-cast-error","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}