diff --git a/src/Psl/Type/Exception/CoercionException.php b/src/Psl/Type/Exception/CoercionException.php
index cf2286cb..128b10fc 100644
--- a/src/Psl/Type/Exception/CoercionException.php
+++ b/src/Psl/Type/Exception/CoercionException.php
@@ -14,10 +14,12 @@ final class CoercionException extends Exception
 {
     private string $target;
 
+    private bool $withValue;
+
     /**
      * @param list<string> $paths
      */
-    private function __construct(?string $actual, string $target, string $message, array $paths = [], ?Throwable $previous = null)
+    private function __construct(?string $actual, string $target, string $message, bool $withValue, array $paths = [], ?Throwable $previous = null)
     {
         parent::__construct(
             $message,
@@ -27,6 +29,7 @@ private function __construct(?string $actual, string $target, string $message, a
         );
 
         $this->target = $target;
+        $this->withValue = $withValue;
     }
 
     public function getTargetType(): string
@@ -52,7 +55,7 @@ public static function withValue(
             $previous && !$previous instanceof self ? ': ' . $previous->getMessage() : '',
         );
 
-        return new self($actual, $target, $message, $paths, $previous);
+        return new self($actual, $target, $message, true, $paths, $previous);
     }
 
     public static function withoutValue(
@@ -69,6 +72,18 @@ public static function withoutValue(
             $previous && !$previous instanceof self ? ': ' . $previous->getMessage() : '',
         );
 
-        return new self(null, $target, $message, $paths, $previous);
+        return new self(null, $target, $message, false, $paths, $previous);
+    }
+
+    public function wrap(
+        mixed $value,
+        string $target,
+        ?string $path = null
+    ): self {
+        if ($this->withValue) {
+            return self::withValue($value, $target, $path, $this);
+        }
+
+        return self::withoutValue($target, $path, $this);
     }
 }
diff --git a/src/Psl/Type/Internal/ShapeType.php b/src/Psl/Type/Internal/ShapeType.php
index ead79632..6116861a 100644
--- a/src/Psl/Type/Internal/ShapeType.php
+++ b/src/Psl/Type/Internal/ShapeType.php
@@ -148,7 +148,7 @@ private function coerceIterable(mixed $value): array
             }
         } catch (CoercionException $e) {
             throw match (true) {
-                $element_value_found => CoercionException::withValue($array[$element] ?? null, $this->toString(), PathExpression::path($element), $e),
+                $element_value_found => $e->wrap($array[$element] ?? null, $this->toString(), PathExpression::path($element)),
                 default => $e
             };
         }
diff --git a/tests/unit/Type/ShapeTypeTest.php b/tests/unit/Type/ShapeTypeTest.php
index e7c1512f..10cf077d 100644
--- a/tests/unit/Type/ShapeTypeTest.php
+++ b/tests/unit/Type/ShapeTypeTest.php
@@ -249,6 +249,17 @@ public static function provideCoerceExceptionExpectations(): iterable
             [],
             'Could not coerce to type "array{\'name\': string}" at path "name" as the value was not passed.'
         ];
+        yield 'missing nested key' => [
+            Type\shape([
+                'a' => Type\shape([
+                    'b' => Type\shape([
+                        'c' => Type\mixed(),
+                    ]),
+                ]),
+            ]),
+            ['a' => ['b' => []]],
+            'Could not coerce to type "array{\'a\': array{\'b\': array{\'c\': mixed}}}" at path "a.b.c" as the value was not passed.',
+        ];
         yield 'invalid key' => [
             Type\shape([
                 'name' => Type\string(),