mongodb/node-mongodb-native · error · MongoRuntimeError

Expected result of decryption to be deserialized BSON object

Error message

Expected result of decryption to be deserialized BSON object

What it means

Thrown by decorateDecryptionResult() when the decrypted value passed in is still a Uint8Array (raw bytes) rather than a deserialized BSON object. In CSFLE/Queryable Encryption flows the driver expects the encryption library to return a deserialized document; receiving raw bytes indicates the decryption layer did not deserialize correctly. Raised as MongoRuntimeError.

Solutions

  1. Ensure the mongodb driver and mongodb-client-encryption versions are compatible per the driver's changelog/peer-dep matrix.
  2. Reinstall dependencies cleanly (rm -rf node_modules && npm install) to fix native binding build issues.
  3. If the error persists, capture the command/response context and file a bug with driver and encryption-library versions.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await client.db('enc').collection('patients').findOne(filter);
} catch (e) {
  if (e instanceof MongoRuntimeError && /Expected result of decryption/.test(e.message)) {
    // align driver and mongodb-client-encryption versions; reinstall native bindings
  } else throw e;
}

Prevention

When it happens

Trigger: Internal CSFLE auto-decryption path where mongodb-client-encryption returns a Uint8Array instead of an object for the decrypted command response. Not triggered by direct user API misuse; indicates an incompatibility between the driver and the encryption native bindings, or a corrupted response.

Common situations: Version mismatch between the mongodb driver and mongodb-client-encryption (libmongocrypt bindings). Corrupt or unexpected server responses when CSFLE is enabled. Seen during driver/encryption-library upgrades if peer dependencies are not updated together.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11). Data as JSON: /api/errors/139c04aa29d566f7. Report an issue: GitHub.

Appendix: source

Thrown at src/utils.ts:1358

 * Recurse through the (identically-shaped) `decrypted` and `original`
 * objects and attach a `decryptedKeys` property on each sub-object that
 * contained encrypted fields. Because we only call this on BSON responses,
 * we do not need to worry about circular references.
 *
 * @internal
 */
export function decorateDecryptionResult(
  decrypted: Document & { [kDecoratedKeys]?: Array<string> },
  original: Document,
  isTopLevelDecorateCall = true
): void {
  if (isTopLevelDecorateCall) {
    // The original value could have been either a JS object or a BSON buffer
    if (ByteUtils.isUint8Array(original)) {
      original = deserialize(original);
    }
    if (ByteUtils.isUint8Array(decrypted)) {
      throw new MongoRuntimeError('Expected result of decryption to be deserialized BSON object');
    }
  }

  if (!decrypted || typeof decrypted !== 'object') return;
  for (const k of Object.keys(decrypted)) {
    const originalValue = original[k];

    // An object was decrypted by libmongocrypt if and only if it was
    // a BSON Binary object with subtype 6.
    if (originalValue && originalValue._bsontype === 'Binary' && originalValue.sub_type === 6) {
      if (!decrypted[kDecoratedKeys]) {
        Object.defineProperty(decrypted, kDecoratedKeys, {
          value: [],
          configurable: true,
          enumerable: false,
          writable: false
        });
      }

View on GitHub (pinned to dce7939f86)