diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp
index 1dedb809..8a3957a6 100644
--- a/include/nlohmann/json.hpp
+++ b/include/nlohmann/json.hpp
@@ -3785,7 +3785,7 @@ class basic_json
     template<class ValueType, typename std::enable_if<
                  std::is_convertible<basic_json_t, ValueType>::value
                  and not std::is_same<value_t, ValueType>::value, int>::type = 0>
-    ValueType value(const typename object_t::key_type& key, ValueType && default_value) const
+    ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
     {
         // at only works for objects
         if (JSON_HEDLEY_LIKELY(is_object()))
@@ -3797,7 +3797,7 @@ class basic_json
                 return *it;
             }
 
-            return std::move(default_value);
+            return default_value;
         }
 
         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
@@ -3809,7 +3809,7 @@ class basic_json
     */
     string_t value(const typename object_t::key_type& key, const char* default_value) const
     {
-        return value(key, std::move(string_t(default_value)));
+        return value(key, string_t(default_value));
     }
 
     /*!
@@ -3857,7 +3857,7 @@ class basic_json
     */
     template<class ValueType, typename std::enable_if<
                  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
-    ValueType value(const json_pointer& ptr, ValueType && default_value) const
+    ValueType value(const json_pointer& ptr, const ValueType& default_value) const
     {
         // at only works for objects
         if (JSON_HEDLEY_LIKELY(is_object()))
@@ -3869,7 +3869,7 @@ class basic_json
             }
             JSON_INTERNAL_CATCH (out_of_range&)
             {
-                return std::move(default_value);
+                return default_value;
             }
         }
 
@@ -3883,7 +3883,7 @@ class basic_json
     JSON_HEDLEY_NON_NULL(3)
     string_t value(const json_pointer& ptr, const char* default_value) const
     {
-        return value(ptr, std::move(string_t(default_value)));
+        return value(ptr, string_t(default_value));
     }
 
     /*!
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
index 87222900..05c3c925 100644
--- a/single_include/nlohmann/json.hpp
+++ b/single_include/nlohmann/json.hpp
@@ -19715,7 +19715,7 @@ class basic_json
     template<class ValueType, typename std::enable_if<
                  std::is_convertible<basic_json_t, ValueType>::value
                  and not std::is_same<value_t, ValueType>::value, int>::type = 0>
-    ValueType value(const typename object_t::key_type& key, ValueType && default_value) const
+    ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
     {
         // at only works for objects
         if (JSON_HEDLEY_LIKELY(is_object()))
@@ -19727,7 +19727,7 @@ class basic_json
                 return *it;
             }
 
-            return std::move(default_value);
+            return default_value;
         }
 
         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
@@ -19739,7 +19739,7 @@ class basic_json
     */
     string_t value(const typename object_t::key_type& key, const char* default_value) const
     {
-        return value(key, std::move(string_t(default_value)));
+        return value(key, string_t(default_value));
     }
 
     /*!
@@ -19787,7 +19787,7 @@ class basic_json
     */
     template<class ValueType, typename std::enable_if<
                  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
-    ValueType value(const json_pointer& ptr, ValueType && default_value) const
+    ValueType value(const json_pointer& ptr, const ValueType& default_value) const
     {
         // at only works for objects
         if (JSON_HEDLEY_LIKELY(is_object()))
@@ -19799,7 +19799,7 @@ class basic_json
             }
             JSON_INTERNAL_CATCH (out_of_range&)
             {
-                return std::move(default_value);
+                return default_value;
             }
         }
 
@@ -19813,7 +19813,7 @@ class basic_json
     JSON_HEDLEY_NON_NULL(3)
     string_t value(const json_pointer& ptr, const char* default_value) const
     {
-        return value(ptr, std::move(string_t(default_value)));
+        return value(ptr, string_t(default_value));
     }
 
     /*!
diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp
index e5cd0337..3f9d9c26 100644
--- a/test/src/unit-regression.cpp
+++ b/test/src/unit-regression.cpp
@@ -1945,6 +1945,15 @@ TEST_CASE("regression tests")
                   )
         );
     }
+
+    SECTION("PR #2181 - regression bug with lvalue")
+    {
+        // see https://github.com/nlohmann/json/pull/2181#issuecomment-653326060
+        json j{{"x", "test"}};
+        std::string defval = "default value";
+        auto val = j.value("x", defval);
+        auto val2 = j.value("y", defval);
+    }
 }
 
 #if not defined(JSON_NOEXCEPTION)
diff --git a/test/src/unit-udt_macro.cpp b/test/src/unit-udt_macro.cpp
index a6b66e95..90d5e1cc 100644
--- a/test/src/unit-udt_macro.cpp
+++ b/test/src/unit-udt_macro.cpp
@@ -60,9 +60,9 @@ class person_with_private_data
 class person_without_private_data_1
 {
   public:
-  std::string name = "";
-  int age = 0;
-  json metadata = nullptr;
+    std::string name = "";
+    int age = 0;
+    json metadata = nullptr;
 
     bool operator==(const person_without_private_data_1& rhs) const
     {
@@ -82,9 +82,9 @@ class person_without_private_data_1
 class person_without_private_data_2
 {
   public:
-  std::string name = "";
-  int age = 0;
-  json metadata = nullptr;
+    std::string name = "";
+    int age = 0;
+    json metadata = nullptr;
 
     bool operator==(const person_without_private_data_2& rhs) const
     {