diff --git a/xarray/core/merge.py b/xarray/core/merge.py
index 6426f741750..db03e7423b0 100644
--- a/xarray/core/merge.py
+++ b/xarray/core/merge.py
@@ -333,6 +333,12 @@ def collect_variables_and_indexes(
         indexes = {}
 
     grouped: dict[Hashable, list[MergeElement]] = defaultdict(list)
+    sizes: dict[Hashable, int] = {
+        k: v
+        for i in list_of_mappings
+        for j in i.values()
+        for k, v in getattr(j, "sizes", {}).items()
+    }
 
     def append(name, variable, index):
         grouped[name].append((variable, index))
@@ -355,7 +361,7 @@ def append_all(variables, indexes):
                 indexes_.pop(name, None)
                 append_all(coords_, indexes_)
 
-            variable = as_variable(variable, name=name, auto_convert=False)
+            variable = as_variable(variable, name=name, auto_convert=False, sizes=sizes)
             if name in indexes:
                 append(name, variable, indexes[name])
             elif variable.dims == (name,):
diff --git a/xarray/core/variable.py b/xarray/core/variable.py
index 088c5f405ef..9ae2487db01 100644
--- a/xarray/core/variable.py
+++ b/xarray/core/variable.py
@@ -86,7 +86,10 @@ class MissingDimensionsError(ValueError):
 
 
 def as_variable(
-    obj: T_DuckArray | Any, name=None, auto_convert: bool = True
+    obj: T_DuckArray | Any,
+    name=None,
+    auto_convert: bool = True,
+    sizes: Mapping | None = None,
 ) -> Variable | IndexVariable:
     """Convert an object into a Variable.
 
@@ -128,10 +131,10 @@ def as_variable(
         obj = obj.copy(deep=False)
     elif isinstance(obj, tuple):
         try:
-            dims_, data_, *attrs = obj
+            dims_, data_, *attrs_ = obj if len(obj) >= 2 else obj + (np.nan,)
         except ValueError as err:
             raise ValueError(
-                f"Tuple {obj} is not in the form (dims, data[, attrs])"
+                f"Tuple {obj} is not in the form (dims, [data[, attrs[, encoding]]])"
             ) from err
 
         if isinstance(data_, DataArray):
@@ -139,12 +142,30 @@ def as_variable(
                 f"Variable {name!r}: Using a DataArray object to construct a variable is"
                 " ambiguous, please extract the data using the .data property."
             )
+
+        if utils.is_scalar(data_, include_0d=False) and sizes is not None:
+            try:
+                shape_ = tuple(sizes[i] for i in dims_)
+            except TypeError as err:
+                message = (
+                    f"Variable {name!r}: Could not convert tuple of form "
+                    f"(dims, [data, [attrs, [encoding]]]): {obj} to Variable."
+                )
+                raise ValueError(message) from err
+            except KeyError as err:
+                message = (
+                    f"Variable {name!r}: Provide `coords` with dimension(s) {dims_} to "
+                    f"initialize with `np.full({dims_}, {data_!r})`."
+                )
+                raise ValueError(message) from err
+            data_ = np.full(shape_, data_)
+
         try:
-            obj = Variable(dims_, data_, *attrs)
+            obj = Variable(dims_, data_, *attrs_)
         except (TypeError, ValueError) as error:
             raise error.__class__(
                 f"Variable {name!r}: Could not convert tuple of form "
-                f"(dims, data[, attrs, encoding]): {obj} to Variable."
+                f"(dims, [data, [attrs, [encoding]]]): {obj} to Variable."
             ) from error
     elif utils.is_scalar(obj):
         obj = Variable([], obj)
diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py
index f3867bd67d2..e265eefe4d4 100644
--- a/xarray/tests/test_dataset.py
+++ b/xarray/tests/test_dataset.py
@@ -476,7 +476,7 @@ def test_constructor(self) -> None:
 
         with pytest.raises(ValueError, match=r"conflicting sizes"):
             Dataset({"a": x1, "b": x2})
-        with pytest.raises(TypeError, match=r"tuple of form"):
+        with pytest.raises(ValueError, match=r"tuple of form"):
             Dataset({"x": (1, 2, 3, 4, 5, 6, 7)})
         with pytest.raises(ValueError, match=r"already exists as a scalar"):
             Dataset({"x": 0, "y": ("x", [1, 2, 3])})
@@ -527,6 +527,51 @@ class Arbitrary:
             actual = Dataset({"x": arg})
             assert_identical(expected, actual)
 
+    def test_constructor_scalar(self) -> None:
+        fill_value = np.nan
+        x = np.arange(2)
+        a = {"foo": "bar"}
+
+        # a suitable `coords`` argument is required
+        with pytest.raises(ValueError):
+            Dataset({"f": (["x"], fill_value), "x": x})
+
+        # 1d coordinates
+        expected = Dataset(
+            {
+                "f": DataArray(fill_value, dims=["x"], coords={"x": x}),
+            },
+        )
+        for actual in (
+            Dataset({"f": (["x"], fill_value)}, coords=expected.coords),
+            Dataset({"f": (["x"], fill_value)}, coords={"x": x}),
+            Dataset({"f": (["x"],)}, coords=expected.coords),
+            Dataset({"f": (["x"],)}, coords={"x": x}),
+        ):
+            assert_identical(expected, actual)
+        expected["f"].attrs.update(a)
+        actual = Dataset({"f": (["x"], fill_value, a)}, coords={"x": x})
+        assert_identical(expected, actual)
+
+        # 2d coordinates
+        yx = np.arange(6).reshape(2, -1)
+        try:
+            # TODO(itcarroll): aux coords broken in DataArray from scalar
+            array = DataArray(
+                fill_value, dims=["y", "x"], coords={"lat": (["y", "x"], yx)}
+            )
+            expected = Dataset({"f": array})
+        except ValueError:
+            expected = Dataset(
+                data_vars={"f": (["y", "x"], np.full(yx.shape, fill_value))},
+                coords={"lat": (["y", "x"], yx)},
+            )
+        actual = Dataset(
+            {"f": (["y", "x"], fill_value)},
+            coords=expected.coords,
+        )
+        assert_identical(expected, actual)
+
     def test_constructor_auto_align(self) -> None:
         a = DataArray([1, 2], [("x", [0, 1])])
         b = DataArray([3, 4], [("x", [1, 2])])