4

There are loads of threads on this issue, none of which have solutions that work for me. I am using NestJS, TypeORM, and Cosmos DB Mongo API.

I am running the NestJS service on my machine, hitting the Database in Azure. I can read from collections fine, but any time I try to write, I get the following error:

MongoError: Retryable writes are not supported. Please disable retryable writes by specifying "retrywrites=false" in the connection string or an equivalent driver specific config.

A stripped down version of the logic that is saving to the DB. The object I am saving works fine when doing db.collection.save() in Mongo Shell in Azure. But the exact same save() fails here

@Injectable()
export class PatientService {

constructor(
    @InjectRepository(PatientsByUser)
    private readonly patientsByUserRepo: MongoRepository<PatientsByUser>
) {}

async addPatientToFavoritesList() {
            this.patientsByUserRepo.save({
                email: "test",
                patientList: [{
                    accountNumber: 1,
                    firstName: "test",
                    lastName: "test",
                    dob: "test"
                }]
            })
  }

}

Here is the module that configures TypeORM:

import {HttpModule, Module} from '@nestjs/common';
import {ConfigModule} from "@nestjs/config";
import {TypeOrmModule} from "@nestjs/typeorm";
import {PatientService} from "./patient.service";
import {PatientController} from "./patient.controller";
import {PatientsByUser} from "./patient.entity";

@Module({
    imports: [
        HttpModule,
        ConfigModule.forRoot(),
        TypeOrmModule.forRoot({
            type: 'mongodb',
            url: process.env.MONGODB_CONNECTION_STRING,
            database: process.env.MONGODB_DATABASE,
            entities: [
                __dirname + '/**/*.entity{.ts,.js}',
            ],
            ssl: true,
            useUnifiedTopology: true,
            useNewUrlParser: true,

        }),
        TypeOrmModule.forFeature([PatientsByUser])
    ],
    providers: [PatientService],
    controllers: [PatientController],
    exports: [PatientService]
})
export class PatientModule {}

My connection string does contain retrywrites=false. I also tried retryWrites=false, and tried both at the end of the connection string. Neither worked.

MONGODB_CONNECTION_STRING=mongodb://portal-db-dev:<private>==@portal-db-dev.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=@portal-db-dev@

Our Cosmos DB is version 4. I am aware that rolling back to 3.2 would fix this, but that would be suboptimal, and completely absurd on Microsoft's part if thats the only way out of this.

package.json

{
  "name": "portal-be",
  "version": "0.0.1",
  "description": "",
  "author": "",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build && mkdir dist/src/assets && cp -r src/assets/* dist/src/assets",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
  "dependencies": {
    "@nestjs/common": "^7.6.13",
    "@nestjs/config": "^0.6.3",
    "@nestjs/core": "^7.6.13",
    "@nestjs/passport": "^7.1.5",
    "@nestjs/platform-express": "^7.6.13",
    "@nestjs/swagger": "^4.7.15",
    "@nestjs/typeorm": "^7.1.5",
    "@types/mongodb": "^3",
    "@types/passport-azure-ad": "^4.0.8",
    "class-transformer": "^0.4.0",
    "class-validator": "^0.13.1",
    "dotenv": "^8.2.0",
    "jwt-decode": "^3.1.2",
    "moment": "^2.29.1",
    "mongodb": "^3.6.9",
    "passport": "^0.4.1",
    "passport-azure-ad": "^4.3.0",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^6.6.7",
    "soap": "^0.39.0",
    "typeorm": "^0.2.32"
  },
  "devDependencies": {
    "@nestjs/cli": "^7.5.6",
    "@nestjs/schematics": "^7.2.7",
    "@nestjs/testing": "^7.6.13",
    "@types/express": "^4.17.11",
    "@types/jest": "^26.0.20",
    "@types/mongodb": "^3",
    "@types/node": "^14.14.31",
    "@types/supertest": "^2.0.10",
    "@typescript-eslint/eslint-plugin": "^4.15.2",
    "@typescript-eslint/parser": "^4.15.2",
    "eslint": "^7.20.0",
    "eslint-config-prettier": "^8.1.0",
    "eslint-plugin-prettier": "^3.3.1",
    "jest": "^26.6.3",
    "prettier": "^2.2.1",
    "supertest": "^6.1.3",
    "ts-jest": "^26.5.2",
    "ts-loader": "^8.0.17",
    "ts-node": "^9.1.1",
    "tsconfig-paths": "^3.9.0",
    "typescript": "^4.1.5"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}
David Makogon
  • 69,407
  • 21
  • 141
  • 189
chxpel
  • 141
  • 2
  • 13

2 Answers2

2

Cosmos DB doesn't support retryable writes.

The mongo shell does not enable retryable writes by default.

MongoDB drivers compatible with MongoDB 4.2 or newer enable retryable writes by default.

The MongoDB Node.JS driver versions 3.3+ are compatible with MongoDB 4.2

To connect to a db server that does not support retryable writes using a driver that enables retryable writes by default, you will need to disable retryable writes by passing retryWrites=false in the connection string URI.

https://docs.mongodb.com/manual/core/retryable-writes/#enabling-retryable-writes

Joe
  • 25,000
  • 3
  • 22
  • 44
  • I have already put retryWrites=flase in the connection string, it is in the post. Is there anything beyond that I can try? – chxpel Jul 01 '21 at 01:25
  • In the post, it is shown all lower case. Make sure it is the correct case. – Joe Jul 01 '21 at 08:34
  • 1
    I have tried every possible combination of every case. The issue lies outside of this flag. The driver inside NestJS is not respecting the flag for some reason. Rolling back to mongo 3.2 fixes this, but using a 6 year old version of a DB is less than ideal – chxpel Jul 01 '21 at 20:42
  • @chxpel try use mongdb 4.x instead of 5.x – lmm333 Mar 20 '23 at 03:57
1

I Have the same problem, but with mongorestore In the connection string I tried retryWrites=false and retrywrites=false and the problem persists. I found and answer that works for me, --writeConcern="{w:0}"

posted here: Mongorestore from localhost to cosmosDb fails with "disable retryable writes by specifying "retrywrites=false"

  • Does this provide a solution to the problem desribed in the question at the top of this page? Then please [edit] more according to [answer]. Or is it a solution for your similar but different problem? Then please delete this. – Yunnosch Sep 08 '22 at 10:38