{"id":"31e7bb5461623773","repo":"mongodb/node-mongodb-native","slug":"argument-size-must-be-a-non-negative-number","errorCode":null,"errorMessage":"Argument \"size\" must be a non-negative number","messagePattern":"Argument \"size\" must be a non-negative number","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/utils.ts","lineNumber":840,"sourceCode":"      return NumberUtils.getInt32LE(firstBuffer, 0);\n    }\n\n    // Unlikely case: an int32 is split across buffers.\n    // Use read and put the returned buffer back on top\n    const top4Bytes = this.read(4);\n    const value = NumberUtils.getInt32LE(top4Bytes, 0);\n\n    // Put it back.\n    this.totalByteLength += 4;\n    this.buffers.unshift(top4Bytes);\n\n    return value;\n  }\n\n  /** Reads the requested number of bytes, optionally consuming them */\n  read(size: number): Uint8Array {\n    if (typeof size !== 'number' || size < 0) {\n      throw new MongoInvalidArgumentError('Argument \"size\" must be a non-negative number');\n    }\n\n    // oversized request returns empty buffer\n    if (size > this.totalByteLength) {\n      return ByteUtils.allocate(0);\n    }\n\n    // We know we have enough, we just don't know how it is spread across chunks\n    // TODO(NODE-4732): alloc API should change based on raw option\n    const result = ByteUtils.allocateUnsafe(size);\n\n    for (let bytesRead = 0; bytesRead < size; ) {\n      const buffer = this.buffers.shift();\n      if (buffer == null) {\n        break;\n      }\n      const bytesRemaining = size - bytesRead;\n      const bytesReadable = Math.min(bytesRemaining, buffer.byteLength);","sourceCodeStart":822,"sourceCodeEnd":858,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/utils.ts#L822-L858","documentation":"Thrown by BufferPool.read() when its `size` argument is not a number or is negative. The BufferPool is an internal helper used by the wire-protocol message stream to slice bytes off buffered network data, so an invalid size indicates a corrupted length prefix or a programming fault inside the driver rather than user input. It surfaces as a MongoInvalidArgumentError.","triggerScenarios":"The driver computing a negative or non-numeric byte count when parsing a server response, typically because the wire-protocol length field was malformed or a buffer was advanced incorrectly. Not reachable through normal public API calls.","commonSituations":"Wire-level corruption from a misbehaving proxy or load balancer rewriting MongoDB traffic; a malformed server response on a non-MongoDB endpoint mistakenly targeted by the driver; an internal regression after a BSON/wire-protocol change.","solutions":["Verify the endpoint is a real MongoDB server (not a proxy returning non-MongoDB bytes); connect directly to a mongod/mongos to isolate.","Upgrade the driver to the latest patch release in case the regression is fixed; if reproducible on latest, file a driver bug with the full stack trace and server version.","If a proxy/load balancer sits in front, bypass it or configure it to operate at L4 (raw TCP) rather than inspecting/rewriting the stream."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await collection.findOne(filter);\n} catch (err) {\n  if (err instanceof MongoInvalidArgumentError && /non-negative number/.test(err.message)) {\n    // internal wire-protocol fault; reconnect against a verified MongoDB endpoint\n    throw new Error('Wire-protocol parse error; verify the endpoint is a MongoDB server', { cause: err });\n  }\n  throw err;\n}","preventionTips":["Connect directly to mongod/mongos to rule out proxy/L7 interception.","Keep the driver on the latest patch release.","If reproducible, collect a packet capture and file a driver bug."],"tags":["wire-protocol","internal","network"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}