Repository: vuejs/core (TypeScript)

Issue:
Multiple v-else directives silently ignored after v-if
### Vue version

3.5.13

### Link to minimal reproduction

https://play.vuejs.org/#eNqNkU9LxDAQxb/KmEsV1l10PS1dwT8L6kFFBS+5lHZas6ZJSNJaKP3uTlJ27UGWvSXv/RjevOnZjTHztkG2YqnLrTAeHPrGXHMlaqOthx4sljBAaXUNCaEJV1zlWjkPtatgHfzT5AGl1PCprSxOkjOu0sU4jgbRx2NtZOaRfgBpIVpoz0W55qzMpEPOog5wT8ZFRBbETGEkbAJdHgMtj4GuplC6mARlM+Yd7VmKar51WlFFfYA5y3VthET7YrygHjhbQXSCl1ENP09R87bB2U7PvzD//kffui5onL1adGhbKmPv+cxW6Ed78/6MHb33Zq2LRhJ9wHxDp2UTMo7YbaMKij3hYtrHeGihqg+36Twqt1sqBA3kEHnO6Ph3B1b/i7ucx1oHrgY2/AIArsUU

### Steps to reproduce

Add an element with a `v-if` condition.

Add a `v-else` element right after it.

Add one or more additional `v-else` elements after that.

Only the last `v-else` is recognized. The rest are silently ignored.

### What is expected?

This syntax should either:

- throw a compile-time error, or
- 
- trigger a warning, or
- 
- at the very least, be caught by the Vue ESLint plugin as invalid usage.

Allowing multiple `v-else` blocks after a single `v-if` is logically invalid and likely always unintentional. It can lead to subtle bugs and confusion during development.



### What is actually happening?

No errors or warnings are shown. Only the last `v-else` is used, and the rest are ignored without any indication.

This makes it easy to introduce bugs, especially in larger templates or when components are modified over time.

### System Info

```shell

```

### Any additional comments?

_No response_


Discussion:

Patch:
diff --git a/packages/compiler-core/src/transforms/vIf.ts b/packages/compiler-core/src/transforms/vIf.ts
index 54c505407a3..8bf5c6a32ff 100644
--- a/packages/compiler-core/src/transforms/vIf.ts
+++ b/packages/compiler-core/src/transforms/vIf.ts
@@ -141,9 +141,9 @@ export function processIf(
       }
 
       if (sibling && sibling.type === NodeTypes.IF) {
-        // Check if v-else was followed by v-else-if
+        // Check if v-else was followed by v-else-if or there are two adjacent v-else
         if (
-          dir.name === 'else-if' &&
+          (dir.name === 'else-if' || dir.name === 'else') &&
           sibling.branches[sibling.branches.length - 1].condition === undefined
         ) {
           context.onError(


Test patch:
diff --git a/packages/compiler-core/__tests__/transforms/vIf.spec.ts b/packages/compiler-core/__tests__/transforms/vIf.spec.ts
index 2c2fedab0d5..73b6e221554 100644
--- a/packages/compiler-core/__tests__/transforms/vIf.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vIf.spec.ts
@@ -301,6 +301,25 @@ describe('compiler: v-if', () => {
       ])
     })
 
+    test('error on adjacent v-else', () => {
+      const onError = vi.fn()
+
+      const {
+        node: { branches },
+      } = parseWithIfTransform(
+        `<div v-if="false"/><div v-else/><div v-else/>`,
+        { onError },
+        0,
+      )
+
+      expect(onError.mock.calls[0]).toMatchObject([
+        {
+          code: ErrorCodes.X_V_ELSE_NO_ADJACENT_IF,
+          loc: branches[branches.length - 1].loc,
+        },
+      ])
+    })
+
     test('error on user key', () => {
       const onError = vi.fn()
       // dynamic