diff --git a/src/backend/parser/parse_cte.c b/src/backend/parser/parse_cte.c
index f4f7041ead..f46d63d451 100644
--- a/src/backend/parser/parse_cte.c
+++ b/src/backend/parser/parse_cte.c
@@ -730,15 +730,15 @@ makeDependencyGraphWalker(Node *node, CteState *cstate)
 				 * In the non-RECURSIVE case, query names are visible to the
 				 * WITH items after them and to the main query.
 				 */
-				ListCell   *cell1;
-
 				cstate->innerwiths = lcons(NIL, cstate->innerwiths);
-				cell1 = list_head(cstate->innerwiths);
 				foreach(lc, stmt->withClause->ctes)
 				{
 					CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
+					ListCell   *cell1;
 
 					(void) makeDependencyGraphWalker(cte->ctequery, cstate);
+					/* note that recursion could mutate innerwiths list */
+					cell1 = list_head(cstate->innerwiths);
 					lfirst(cell1) = lappend((List *) lfirst(cell1), cte);
 				}
 				(void) raw_expression_tree_walker(node,
@@ -1006,15 +1006,15 @@ checkWellFormedRecursionWalker(Node *node, CteState *cstate)
 				 * In the non-RECURSIVE case, query names are visible to the
 				 * WITH items after them and to the main query.
 				 */
-				ListCell   *cell1;
-
 				cstate->innerwiths = lcons(NIL, cstate->innerwiths);
-				cell1 = list_head(cstate->innerwiths);
 				foreach(lc, stmt->withClause->ctes)
 				{
 					CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
+					ListCell   *cell1;
 
 					(void) checkWellFormedRecursionWalker(cte->ctequery, cstate);
+					/* note that recursion could mutate innerwiths list */
+					cell1 = list_head(cstate->innerwiths);
 					lfirst(cell1) = lappend((List *) lfirst(cell1), cte);
 				}
 				checkWellFormedSelectStmt(stmt, cstate);
diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out
index c519a61c4f..be4ba1825f 100644
--- a/src/test/regress/expected/with.out
+++ b/src/test/regress/expected/with.out
@@ -176,6 +176,29 @@ ERROR:  operator does not exist: text + integer
 LINE 4:     SELECT n+1 FROM t WHERE n < 10
                     ^
 HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.
+-- Deeply nested WITH caused a list-munging problem in v13
+with recursive w1(c1) as
+ (with w2(c2) as
+  (with w3(c3) as
+   (with w4(c4) as
+    (with w5(c5) as
+     (with recursive w6(c6) as
+      (with w6(c6) as
+       (with w8(c8) as
+        (select 1)
+        select * from w8)
+       select * from w6)
+      select * from w6)
+     select * from w5)
+    select * from w4)
+   select * from w3)
+  select * from w2)
+select * from w1;
+ c1 
+----
+  1
+(1 row)
+
 --
 -- Some examples with a tree
 --
diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql
index f4ba0d8e39..b2f9ac07e8 100644
--- a/src/test/regress/sql/with.sql
+++ b/src/test/regress/sql/with.sql
@@ -95,6 +95,25 @@ UNION ALL
 )
 SELECT n, pg_typeof(n) FROM t;
 
+-- Deeply nested WITH caused a list-munging problem in v13
+with recursive w1(c1) as
+ (with w2(c2) as
+  (with w3(c3) as
+   (with w4(c4) as
+    (with w5(c5) as
+     (with recursive w6(c6) as
+      (with w6(c6) as
+       (with w8(c8) as
+        (select 1)
+        select * from w8)
+       select * from w6)
+      select * from w6)
+     select * from w5)
+    select * from w4)
+   select * from w3)
+  select * from w2)
+select * from w1;
+
 --
 -- Some examples with a tree
 --
