{"id":"139c04aa29d566f7","repo":"mongodb/node-mongodb-native","slug":"expected-result-of-decryption-to-be-deserialized-b","errorCode":null,"errorMessage":"Expected result of decryption to be deserialized BSON object","messagePattern":"Expected result of decryption to be deserialized BSON object","errorType":"exception","errorClass":"MongoRuntimeError","httpStatus":null,"severity":"critical","filePath":"src/utils.ts","lineNumber":1358,"sourceCode":" * Recurse through the (identically-shaped) `decrypted` and `original`\n * objects and attach a `decryptedKeys` property on each sub-object that\n * contained encrypted fields. Because we only call this on BSON responses,\n * we do not need to worry about circular references.\n *\n * @internal\n */\nexport function decorateDecryptionResult(\n  decrypted: Document & { [kDecoratedKeys]?: Array<string> },\n  original: Document,\n  isTopLevelDecorateCall = true\n): void {\n  if (isTopLevelDecorateCall) {\n    // The original value could have been either a JS object or a BSON buffer\n    if (ByteUtils.isUint8Array(original)) {\n      original = deserialize(original);\n    }\n    if (ByteUtils.isUint8Array(decrypted)) {\n      throw new MongoRuntimeError('Expected result of decryption to be deserialized BSON object');\n    }\n  }\n\n  if (!decrypted || typeof decrypted !== 'object') return;\n  for (const k of Object.keys(decrypted)) {\n    const originalValue = original[k];\n\n    // An object was decrypted by libmongocrypt if and only if it was\n    // a BSON Binary object with subtype 6.\n    if (originalValue && originalValue._bsontype === 'Binary' && originalValue.sub_type === 6) {\n      if (!decrypted[kDecoratedKeys]) {\n        Object.defineProperty(decrypted, kDecoratedKeys, {\n          value: [],\n          configurable: true,\n          enumerable: false,\n          writable: false\n        });\n      }","sourceCodeStart":1340,"sourceCodeEnd":1376,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/utils.ts#L1340-L1376","documentation":"Thrown by decorateDecryptionResult() when, after libmongocrypt returns a decrypted response, that response is still a raw Uint8Array instead of a deserialized BSON object. decorateDecryptionResult walks the decrypted object to mark fields that were encrypted, so it requires an object, not bytes. Hitting this means the CSFLE/Queryable-Encryption decryption pipeline returned bytes where the driver expected an object, typically indicating a version mismatch or a bug in the encryption bindings. It surfaces as a MongoRuntimeError from connection.ts and wire_protocol/responses.ts.","triggerScenarios":"Running Client-Side Field Level Encryption (CSFLE) or Queryable Encryption where the installed mongodb-client-encryption native binding is incompatible with the driver version; a custom crypt shared library returning an unexpected shape; an internal regression in the decrypt->deserialize ordering.","commonSituations":"Upgrading the driver without upgrading mongodb-client-encryption (or vice versa); a broken/incomplete native build of libmongocrypt; mismatched crypt_shared library version; environment where the native addon failed to load and fell back to a code path that returns bytes.","solutions":["Align versions: use the mongodb-client-encryption (and mongocryptd / crypt_shared) version documented as compatible with your mongodb driver version.","Rebuild native dependencies (npm rebuild / reinstall) so the libmongocrypt binding compiles and loads correctly.","Point to a compatible crypt_shared library via the cryptSharedLibPath option, or remove it to use mongocryptd.","If the issue persists on matched, freshly-built versions, capture the driver + encryption library versions and file a driver bug with the schema and a minimal repro."],"exampleFix":"// before: driver and encryption lib mismatched\nconst client = new MongoClient(uri, { autoEncryption: { ... } }); // => MongoRuntimeError on first query\n\n// after: pin compatible versions in package.json\n// \"mongodb\": \"^6.5.0\",\n// \"mongodb-client-encryption\": \"^6.0.0\"\n// then: rm -rf node_modules && npm install","handlingStrategy":"try-catch","validationCode":"import { MongoClient } from 'mongodb';\nfunction assertEncryptionCompat(driverVer: string, encVer: string): void {\n  // enforce a known-good combination per the driver's compatibility matrix\n  const ok = driverVer.startsWith('6.') && encVer.startsWith('6.');\n  if (!ok) throw new Error(`Unsupported driver/encryption combo: mongodb ${driverVer} + mongodb-client-encryption ${encVer}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await encryptedCollection.findOne(filter);\n} catch (err) {\n  if (err instanceof MongoRuntimeError && /Expected result of decryption to be deserialized BSON/.test(err.message)) {\n    throw new Error('CSFLE decryption pipeline mismatch; align mongodb and mongodb-client-encryption versions and rebuild natives', { cause: err });\n  }\n  throw err;\n}","preventionTips":["Keep mongodb and mongodb-client-encryption on versions documented as compatible.","Rebuild native modules after node/OS upgrades (npm rebuild).\n        ","Pin a known-good crypt_shared library via cryptSharedLibPath or use mongocryptd explicitly.","Smoke-test encryption with a trivial insert/find at deploy time to catch mismatch early."],"tags":["csfle","encryption","native","version-mismatch"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}