diff --git a/R/CreateInputsModel.GRiwrm.R b/R/CreateInputsModel.GRiwrm.R
index 55d73e60fc5752c839b01a746652ce4b8579849b..d3e8b3244fe0977a498c0d2ff3b70388af542e2a 100644
--- a/R/CreateInputsModel.GRiwrm.R
+++ b/R/CreateInputsModel.GRiwrm.R
@@ -16,6 +16,9 @@
 #' @param Qmin (optional) [matrix] or [data.frame] of [numeric] containing
 #'        minimum flows to let downstream of a node with a Diversion \[m3 per
 #'        time step\]. Default is zero. Column names correspond to node IDs
+#' @param Qrelease (optional) [matrix] or [data.frame] of [numeric] containing
+#'        release flows by nodes using the model `RunModel_Reservoir` \[m3 per
+#'        time step\]
 #' @param PrecipScale (optional) named [vector] of [logical] indicating if the
 #'        mean of the precipitation interpolated on the elevation layers must be
 #'        kept or not, required to create CemaNeige module inputs, default `TRUE`
@@ -69,6 +72,7 @@ CreateInputsModel.GRiwrm <- function(x, DatesR,
                                      PotEvap = NULL,
                                      Qobs = NULL,
                                      Qmin = NULL,
+                                     Qrelease = NULL,
                                      PrecipScale = TRUE,
                                      TempMean = NULL, TempMin = NULL,
                                      TempMax = NULL, ZInputs = NULL,
@@ -120,31 +124,14 @@ CreateInputsModel.GRiwrm <- function(x, DatesR,
     }
   })
 
-  directFlowIds <- x$id[is.na(x$model) | x$model == "Diversion" | x$model == "RunModel_Reservoir"]
-  if (length(directFlowIds) > 0) {
-    err <- FALSE
-    if (is.null(Qobs)) {
-      err <- TRUE
-    } else {
-      Qobs <- as.matrix(Qobs)
-      if (is.null(colnames(Qobs))) {
-        err <- TRUE
-      } else if (!all(directFlowIds %in% colnames(Qobs))) {
-        err <- TRUE
-      }
-    }
-    if (err) stop(sprintf("'Qobs' column names must at least contain %s", paste(directFlowIds, collapse = ", ")))
-  }
-  if (!all(colnames(Qobs) %in% directFlowIds)) {
-    warning(
-      "The following columns in 'Qobs' are ignored since they don't match with ",
-      "Direction Injection (model=`NA`), ",
-      "Reservoir (model=\"RunModelReservoir\"), ",
-      "or Diversion nodes (model=\"Diversion\"): ",
-      paste(setdiff(colnames(Qobs), directFlowIds), collapse = ", ")
-    )
-    Qobs <- Qobs[, directFlowIds]
-  }
+  if (is.null(Qobs)) Qobs <- matrix(0, ncol = 0, nrow = length(DatesR))
+  if (is.null(Qrelease)) Qrelease <- matrix(0, ncol = 0, nrow = length(DatesR))
+  l <- updateQObsQrelease(g = x, Qobs = Qobs, Qrelease = Qrelease)
+  Qobs <- l$Qobs
+  Qrelease <- l$Qrelease
+  checkQobsQrelease(x, "Qobs", Qobs)
+  checkQobsQrelease(x, "Qrelease", Qrelease)
+
   diversionRows <- getDiversionRows(x)
   if (length(diversionRows) > 0) {
     warn <- FALSE
@@ -171,7 +158,7 @@ CreateInputsModel.GRiwrm <- function(x, DatesR,
       warning(
         sprintf(
           "'Qmin' would include the following columns %s.\n Zero values are applied by default.",
-          paste(directFlowIds, collapse = ", ")
+          paste(x$id[diversionRows], collapse = ", ")
         )
       )
     }
@@ -188,16 +175,6 @@ CreateInputsModel.GRiwrm <- function(x, DatesR,
 
   InputsModel <- CreateEmptyGRiwrmInputsModel(x)
 
-  # Qobs completion for at least filling Qupstream of all nodes by zeros
-  Qobs0 <- matrix(0, nrow = length(DatesR), ncol = nrow(x))
-  colnames(Qobs0) <- x$id
-  if (is.null(Qobs)) {
-    Qobs <- Qobs0
-  } else {
-    Qobs0[, colnames(Qobs)] <- Qobs
-    Qobs <- Qobs0
-  }
-
   for(id in getNodeRanking(x)) {
     message("CreateInputsModel.GRiwrm: Processing sub-basin ", id, "...")
 
@@ -216,6 +193,7 @@ CreateInputsModel.GRiwrm <- function(x, DatesR,
                                  NLayers = getInputBV(NLayers, id, 5),
                                  Qobs = Qobs,
                                  Qmin = getInputBV(Qmin, id),
+                                 Qrelease = Qrelease,
                                  IsHyst = IsHyst
                                  )
   }
@@ -251,7 +229,7 @@ CreateEmptyGRiwrmInputsModel <- function(griwrm) {
 #'
 #' @return \emph{InputsModel} object for one.
 #' @noRd
-CreateOneGRiwrmInputsModel <- function(id, griwrm, ..., Qobs, Qmin, IsHyst) {
+CreateOneGRiwrmInputsModel <- function(id, griwrm, DatesR, ..., Qobs, Qmin, Qrelease, IsHyst) {
   np <- getNodeProperties(id, griwrm)
 
   if (np$Diversion) {
@@ -272,7 +250,20 @@ CreateOneGRiwrmInputsModel <- function(id, griwrm, ..., Qobs, Qmin, IsHyst) {
 
   if(length(UpstreamNodeRows) > 0) {
     # Sub-basin with hydraulic routing
-    Qupstream <- as.matrix(Qobs[ , griwrm$id[UpstreamNodeRows], drop=FALSE])
+    Qupstream <- NULL
+    Qupstream <- as.matrix(cbind(
+      Qobs[ , colnames(Qobs)[colnames(Qobs) %in% griwrm$id[UpstreamNodeRows]], drop = FALSE],
+      Qrelease[ , colnames(Qrelease)[colnames(Qrelease) %in% griwrm$id[UpstreamNodeRows]], drop = FALSE]
+    ))
+    # Qupstream completion with zeros for all upstream nodes
+    Qupstream0 <- matrix(0, nrow = length(DatesR), ncol = length(UpstreamNodeRows))
+    colnames(Qupstream0) <- griwrm$id[UpstreamNodeRows]
+    if (is.null(Qupstream) || ncol(Qupstream) == 0) {
+      Qupstream <- Qupstream0
+    } else {
+      Qupstream0[, colnames(Qupstream)] <- Qupstream
+      Qupstream <- Qupstream0
+    }
     upstreamDiversion <- which(
       sapply(griwrm$id[UpstreamNodeRows],
              function(id) {
@@ -308,6 +299,7 @@ CreateOneGRiwrmInputsModel <- function(id, griwrm, ..., Qobs, Qmin, IsHyst) {
   # Set model inputs with the **airGR** function
   InputsModel <- CreateInputsModel(
     FUN_MOD,
+    DatesR = DatesR,
     ...,
     Qupstream = Qupstream,
     LengthHydro = LengthHydro,
@@ -352,7 +344,8 @@ CreateOneGRiwrmInputsModel <- function(id, griwrm, ..., Qobs, Qmin, IsHyst) {
     InputsModel$diversionOutlet <- diversionOutlet
     InputsModel$Qdiv <- -Qobs[, id]
     InputsModel$Qmin <- Qmin
-  } else if(np$Reservoir) {
+  }
+  if (np$Reservoir) {
     # If an upstream node is ungauged and the donor is downstream then we are in an ungauged reduced network
     iUpstreamUngaugedNodes <- which(griwrm$id %in% griwrm$id[UpstreamNodeRows] &
                                     griwrm$model == "Ungauged")
@@ -361,7 +354,7 @@ CreateOneGRiwrmInputsModel <- function(id, griwrm, ..., Qobs, Qmin, IsHyst) {
       InputsModel$isUngauged <- any(griwrm$donor[iUpstreamUngaugedNodes] == InputsModel$gaugedId)
     }
     # Fill reservoir release with Qobs
-    InputsModel$Qrelease <- Qobs[, id]
+    InputsModel$Qrelease <- Qrelease[, id]
   }
 
   # Add class for S3 process (Prequel of HYCAR-Hydro/airgr#60)
diff --git a/R/RunModel.InputsModel.R b/R/RunModel.InputsModel.R
index f36e4b0e4a08f524678c1c1107cdba6b2aa888fb..8fb7a70e4c1271bb9dd5077bc7d57cd071af732a 100644
--- a/R/RunModel.InputsModel.R
+++ b/R/RunModel.InputsModel.R
@@ -70,7 +70,7 @@ RunModel.InputsModel <- function(x = NULL,
     OutputsModel$RunOptions$WarmUpQsim_m3 <-
       OutputsModel$RunOptions$WarmUpQsim * sum(x$BasinAreas, na.rm = TRUE) * 1e3
   }
-  if (x$hasDiversion) {
+  if (x$hasDiversion && !x$isReservoir) {
     OutputsModel <- RunModel_Diversion(x, RunOptions, OutputsModel)
   }
   return(OutputsModel)
diff --git a/R/RunModel_Reservoir.R b/R/RunModel_Reservoir.R
index 0fff58a478736696bf4147ef5187d906cea377d1..3e20530576207bc9c1744900d5c410282e5530c6 100644
--- a/R/RunModel_Reservoir.R
+++ b/R/RunModel_Reservoir.R
@@ -68,10 +68,17 @@ RunModel_Reservoir <- function(InputsModel, RunOptions, Param) {
   iPerTot <- seq(length(IndPerTot))
   Vsim <- rep(0, length(IndPerTot))
   Qsim_m3 <- Vsim
+  if (InputsModel$hasDiversion) {
+    Qdiv_m3 <- Vsim
+  }
 
   # Time series volume and release calculation
   for(i in iPerTot) {
     Vsim[i] <- V0 + Qinflows_m3[i]
+    if (InputsModel$hasDiversion) {
+      Qdiv_m3[i] <- min(Vsim[i] + InputsModel$Qmin[IndPerTot[i]], InputsModel$Qdiv[IndPerTot[i]])
+      Vsim[i] <- Vsim[i] - Qdiv_m3[i]
+    }
     Qsim_m3[i] <- min(Vsim[i], InputsModel$Qrelease[IndPerTot[i]])
     Vsim[i] <- Vsim[i] - Qsim_m3[i]
     if (Vsim[i] > Vmax) {
@@ -86,10 +93,16 @@ RunModel_Reservoir <- function(InputsModel, RunOptions, Param) {
     iWarmUp <- seq(length(RunOptions$IndPeriod_WarmUp))
     OutputsModel$RunOptions$WarmUpQsim_m3 <- Qsim_m3[iWarmUp]
     OutputsModel$RunOptions$WarmUpVsim <- Vsim[iWarmUp]
+    if (InputsModel$hasDiversion) {
+      OutputsModel$RunOptions$WarmUpQdiv_m3 <- Qdiv_m3[iWarmUp]
+    }
   }
   iRun <- length(IndPerWarmUp) + seq(length(RunOptions$IndPeriod_Run))
   OutputsModel$Qsim_m3 <- Qsim_m3[iRun]
   OutputsModel$Vsim <- Vsim[iRun]
+  if (InputsModel$hasDiversion) {
+    OutputsModel$Qdiv_m3 <- Qdiv_m3[iRun]
+  }
   OutputsModel$StateEnd$Reservoir <- list(V = Vsim[length(Vsim)])
   class(OutputsModel) <- c("OutputsModelReservoir", class(OutputsModel))
   return(OutputsModel)
diff --git a/R/utils.CreateInputsModel.R b/R/utils.CreateInputsModel.R
new file mode 100644
index 0000000000000000000000000000000000000000..c5a4ab9481327ec8df388d96361540e45ea50f34
--- /dev/null
+++ b/R/utils.CreateInputsModel.R
@@ -0,0 +1,59 @@
+updateQObsQrelease <- function(g, Qobs, Qrelease) {
+  reservoirIds <- g$id[!is.na(g$model) & g$model == "RunModel_Reservoir"]
+  # Fill Qrelease with Qobs
+  warn_ids <- NULL
+  for(id in reservoirIds) {
+    if (!id %in% colnames(Qrelease)) {
+      if (id %in% colnames(Qobs)) {
+        if (!any(g$id == id & (!is.na(g$model) & g$model == "Diversion"))) {
+          if (is.null(Qrelease)) {
+            Qrelease = Qobs[, id, drop = FALSE]
+          } else {
+            Qrelease = cbind(Qrelease, Qobs[, id, drop = FALSE])
+          }
+          Qobs <- Qobs[, colnames(Qobs) != id, drop = FALSE]
+          warn_ids = c(warn_ids, id)
+        }
+      }
+    }
+  }
+  if (!is.null(warn_ids)) {
+    warning("Use of the `Qobs` parameter for reservoir releases is deprecated, please use `Qrelease` instead.\n",
+            "Processing `Qrelease <- cbind(Qrelease, Qobs[, c(\"", paste(warn_ids, collapse = "\", `"), "\"])`...")
+  }
+  return(list(Qobs = Qobs, Qrelease = Qrelease))
+}
+
+checkQobsQrelease <- function(g, varname, Q) {
+  if (varname == "Qobs") {
+    directFlowIds <- g$id[is.na(g$model) | g$model == "Diversion"]
+  } else {
+    directFlowIds <- g$id[!is.na(g$model) & g$model == "RunModel_Reservoir"]
+  }
+  if (length(directFlowIds) > 0) {
+    err <- FALSE
+    if (is.null(Q)) {
+      err <- TRUE
+    } else {
+      Q <- as.matrix(Q)
+      if (is.null(colnames(Q))) {
+        err <- TRUE
+      } else if (!all(directFlowIds %in% colnames(Q))) {
+        err <- TRUE
+      }
+    }
+    if (err) stop(sprintf("'%s' column names must at least contain %s", varname, paste(directFlowIds, collapse = ", ")))
+  }
+  if (!all(colnames(Q) %in% directFlowIds)) {
+    warning(
+      sprintf("The following columns in '%s' are ignored since they don't match with ", varname),
+      ifelse(varname == "Qobs",
+             c("Direction Injection (model=`NA`), ",
+               "or Diversion nodes (model=\"Diversion\"): "),
+             "Reservoir nodes (model=\"RunModelReservoir\"): "),
+      paste(setdiff(colnames(Q), directFlowIds), collapse = ", ")
+    )
+    Q <- Q[, directFlowIds]
+  }
+  return(Q)
+}
diff --git a/man/CreateInputsModel.GRiwrm.Rd b/man/CreateInputsModel.GRiwrm.Rd
index 26b9a66bc318a276b31f98ce25216ad896e2e9db..08a947ba73830f918da711b6fbd399a949f0b7df 100644
--- a/man/CreateInputsModel.GRiwrm.Rd
+++ b/man/CreateInputsModel.GRiwrm.Rd
@@ -11,6 +11,7 @@
   PotEvap = NULL,
   Qobs = NULL,
   Qmin = NULL,
+  Qrelease = NULL,
   PrecipScale = TRUE,
   TempMean = NULL,
   TempMin = NULL,
@@ -45,6 +46,10 @@ the model and positive flows are injected to the model}
 minimum flows to let downstream of a node with a Diversion [m3 per
 time step]. Default is zero. Column names correspond to node IDs}
 
+\item{Qrelease}{(optional) \link{matrix} or \link{data.frame} of \link{numeric} containing
+release flows by nodes using the model \code{RunModel_Reservoir} [m3 per
+time step]}
+
 \item{PrecipScale}{(optional) named \link{vector} of \link{logical} indicating if the
 mean of the precipitation interpolated on the elevation layers must be
 kept or not, required to create CemaNeige module inputs, default \code{TRUE}
diff --git a/tests/testthat/helper_1_RunModel.R b/tests/testthat/helper_1_RunModel.R
index 6db2a92ac21ebb1bded8fdebe629a116cfa74f1a..ef1d0b7cf85fa9ebf32c16f8739a224e2616a20d 100644
--- a/tests/testthat/helper_1_RunModel.R
+++ b/tests/testthat/helper_1_RunModel.R
@@ -16,6 +16,7 @@ setupRunModel <-
            runRunModel = TRUE,
            griwrm = NULL,
            Qobs2 = NULL,
+           Qrelease = NULL,
            IsHyst = FALSE) {
 
     data(Severn)
@@ -50,6 +51,49 @@ setupRunModel <-
       TempMean <- NULL
     }
 
+    # Calibration parameters
+    ParamMichel <- list(
+      `54057` = c(
+        0.781180650559296,
+        74.4247133147015,
+        -1.26590474908235,
+        0.96012365697022,
+        2.51101785373787
+      ),
+      `54032` = c(
+        0.992743594649893,
+        1327.19309205366,
+        -0.505902143697436,
+        7.91553615210291,
+        2.03604525989572
+      ),
+      `54001` = c(
+        1.03,
+        24.7790862245877,
+        -1.90430150145153,
+        21.7584023961971,
+        1.37837837837838
+      ),
+      `54095` = c(
+        256.844150254651,
+        0.0650458497009288,
+        57.523675209819,
+        2.71809513102128
+      ),
+      `54002` = c(
+        419.437754485522,
+        0.12473266292168,
+        13.0379482833606,
+        2.12230907892238
+      ),
+      `54029` = c(
+        219.203385553954,
+        0.389211590110934,
+        48.4242150713452,
+        2.00300300300301
+      )
+    )
+
     # set up inputs
     if (!runInputsModel)
       return(environment())
@@ -57,6 +101,7 @@ setupRunModel <-
       suppressWarnings(CreateInputsModel(griwrm, DatesR, Precip, PotEvap,
                                          TempMean = TempMean,
                                          Qobs = Qobs2,
+                                         Qrelease = Qrelease,
                                          IsHyst = IsHyst))
 
     # RunOptions
@@ -83,49 +128,5 @@ setupRunOptions <- function(InputsModel) {
   RunOptions <- CreateRunOptions(InputsModel,
                                  IndPeriod_WarmUp = IndPeriod_WarmUp,
                                  IndPeriod_Run = IndPeriod_Run)
-
-  # Calibration parameters
-  ParamMichel <- list(
-    `54057` = c(
-      0.781180650559296,
-      74.4247133147015,
-      -1.26590474908235,
-      0.96012365697022,
-      2.51101785373787
-    ),
-    `54032` = c(
-      0.992743594649893,
-      1327.19309205366,
-      -0.505902143697436,
-      7.91553615210291,
-      2.03604525989572
-    ),
-    `54001` = c(
-      1.03,
-      24.7790862245877,
-      -1.90430150145153,
-      21.7584023961971,
-      1.37837837837838
-    ),
-    `54095` = c(
-      256.844150254651,
-      0.0650458497009288,
-      57.523675209819,
-      2.71809513102128
-    ),
-    `54002` = c(
-      419.437754485522,
-      0.12473266292168,
-      13.0379482833606,
-      2.12230907892238
-    ),
-    `54029` = c(
-      219.203385553954,
-      0.389211590110934,
-      48.4242150713452,
-      2.00300300300301
-    )
-  )
-
   return(environment())
 }
diff --git a/tests/testthat/test-CreateInputsModel.R b/tests/testthat/test-CreateInputsModel.R
index f8695a76068709e601d1413ed788cacfc7b087c6..fa6acf9d2a2575f7ebcadebd14c8e00929b125f4 100644
--- a/tests/testthat/test-CreateInputsModel.R
+++ b/tests/testthat/test-CreateInputsModel.R
@@ -272,3 +272,12 @@ test_that("Node with upstream nodes having area = NA should return correct Basin
   expect_equal(sum(InputsModel$`54001`$BasinAreas),
                g$area[g$id == "54001"])
 })
+
+test_that("Use of Qobs for Qrelease should raise a warning",  {
+  g <- CreateGRiwrm(n_rsrvr)
+  e <- setupRunModel(griwrm = g, runInputsModel = FALSE)
+  for(x in ls(e)) assign(x, get(x, e))
+  expect_warning(CreateInputsModel(griwrm, DatesR, Precip, PotEvap,
+                                   TempMean = TempMean,
+                                   Qobs = Qobs_rsrvr))
+})
diff --git a/tests/testthat/test-CreateSupervisor.R b/tests/testthat/test-CreateSupervisor.R
index 3ba3e848c467626651b4147bec5d774bcda3d480..a484f708895b9a646ce0fdf56eeaac600e360bbb 100644
--- a/tests/testthat/test-CreateSupervisor.R
+++ b/tests/testthat/test-CreateSupervisor.R
@@ -54,7 +54,7 @@ test_that("CreateSupervisor using reservoir and diversion", {
   ))
   g <- CreateGRiwrm(nodes)
   # Add Qobs for the 2 new nodes and create InputsModel
-  Qobs <- matrix(data = rep(0, 2*length(DatesR)), ncol = 2)
+  Qobs <- matrix(data = 0, ncol = 2, nrow = length(DatesR))
   colnames(Qobs) <- c("54029", "Reservoir")
   InputsModel <- suppressWarnings(
       CreateInputsModel(g, DatesR, Precip, PotEvap, Qobs)
diff --git a/tests/testthat/test-RunModel_Reservoir.R b/tests/testthat/test-RunModel_Reservoir.R
index bd227a0947ed96808fe4934c159e356ca97355c9..7417935bf54e330d38bc31df006271aeac34de6a 100644
--- a/tests/testthat/test-RunModel_Reservoir.R
+++ b/tests/testthat/test-RunModel_Reservoir.R
@@ -98,3 +98,40 @@ test_that("Calibration with ungauged node and reservoir filled by a diversion wo
   colnames(Qobs2) <- c("Dam", "54095")
   expect_dam(n_derived_rsrvr, Qobs2)
 })
+
+test_that("Diversion on a reservoir works #146", {
+  e <- setupRunModel(runInputsModel = FALSE)
+  for (x in ls(e)) assign(x, get(x, e))
+  Qrelease <- data.frame(Dam = rep(3508465, length(DatesR)))
+  Param <- c(ParamMichel[names(ParamMichel) %in% griwrm$id], list(Dam = c(10E6, 1)))
+  e <- setupRunModel(runRunModel = FALSE,
+                     griwrm = CreateGRiwrm(n_rsrvr),
+                     Qrelease = Qrelease)
+  for (x in ls(e)) assign(x, get(x, e))
+  OM_resOnly <- RunModel(InputsModel,
+                         RunOptions = RunOptions,
+                         Param = Param)
+  nodes <- rbind(
+    n_rsrvr,
+    data.frame(
+      id = "Dam",
+      down = NA,
+      length = NA,
+      area = NA,
+      model = "Diversion"
+    )
+  )
+  Qobs2 <- Qrelease * 0.1
+  g <- CreateGRiwrm(nodes)
+  e <- setupRunModel(griwrm = g,
+                     runRunModel = FALSE,
+                     Qobs2 = Qobs2,
+                     Qrelease = Qrelease)
+  for (x in ls(e)) assign(x, get(x, e))
+
+  OM <- RunModel(InputsModel,
+                 RunOptions = RunOptions,
+                 Param = Param)
+  expect_true(max(OM$Dam$Vsim) - min(OM$Dam$Vsim) > 0)
+  expect_false(all(OM$Dam$Vsim == OM_resOnly$Dam$Vsim))
+})