From fe4fb460b1b0bb1373684541c7cbc107b582e789 Mon Sep 17 00:00:00 2001 From: Maksim Romanov Date: Tue, 6 Oct 2026 12:01:44 +0200 Subject: [PATCH] fix: error if `{:else}` is followed by another `{:else}` or `{:else if ...}` (#18900) Fixes #18202 --- .changeset/duplicate-else-clause.md | 5 +++++ packages/svelte/src/compiler/phases/1-parse/state/tag.js | 2 ++ .../samples/each-block-duplicate-else/_config.js | 9 +++++++++ .../samples/each-block-duplicate-else/main.svelte | 7 +++++++ .../samples/if-block-else-before-else-if/_config.js | 9 +++++++++ .../samples/if-block-else-before-else-if/main.svelte | 7 +++++++ 6 files changed, 39 insertions(+) create mode 100644 .changeset/duplicate-else-clause.md create mode 100644 packages/svelte/tests/compiler-errors/samples/each-block-duplicate-else/_config.js create mode 100644 packages/svelte/tests/compiler-errors/samples/each-block-duplicate-else/main.svelte create mode 100644 packages/svelte/tests/compiler-errors/samples/if-block-else-before-else-if/_config.js create mode 100644 packages/svelte/tests/compiler-errors/samples/if-block-else-before-else-if/main.svelte diff --git a/.changeset/duplicate-else-clause.md b/.changeset/duplicate-else-clause.md new file mode 100644 index 0000000000..5b2ecbbbd5 --- /dev/null +++ b/.changeset/duplicate-else-clause.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: error if `{:else}` is followed by another `{:else}` or `{:else if ...}` diff --git a/packages/svelte/src/compiler/phases/1-parse/state/tag.js b/packages/svelte/src/compiler/phases/1-parse/state/tag.js index 97095e993a..24b74699f6 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/tag.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/tag.js @@ -532,6 +532,7 @@ function next(parser) { if (block.type === 'IfBlock') { if (!parser.eat('else')) e.expected_token(start, '{:else} or {:else if}'); if (parser.eat('if')) e.block_invalid_elseif(start); + if (block.alternate) e.block_duplicate_clause(start, '{:else}'); parser.allow_whitespace(); @@ -580,6 +581,7 @@ function next(parser) { if (block.type === 'EachBlock') { if (!parser.eat('else')) e.expected_token(start, '{:else}'); + if (block.fallback) e.block_duplicate_clause(start, '{:else}'); parser.allow_whitespace(); parser.eat('}', true); diff --git a/packages/svelte/tests/compiler-errors/samples/each-block-duplicate-else/_config.js b/packages/svelte/tests/compiler-errors/samples/each-block-duplicate-else/_config.js new file mode 100644 index 0000000000..fe6bb3c006 --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/each-block-duplicate-else/_config.js @@ -0,0 +1,9 @@ +import { test } from '../../test'; + +export default test({ + error: { + code: 'block_duplicate_clause', + message: '{:else} cannot appear more than once within a block', + position: [42, 42] + } +}); diff --git a/packages/svelte/tests/compiler-errors/samples/each-block-duplicate-else/main.svelte b/packages/svelte/tests/compiler-errors/samples/each-block-duplicate-else/main.svelte new file mode 100644 index 0000000000..6f9a0d7c68 --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/each-block-duplicate-else/main.svelte @@ -0,0 +1,7 @@ +{#each items as item} + {item} +{:else} + A +{:else} + B +{/each} diff --git a/packages/svelte/tests/compiler-errors/samples/if-block-else-before-else-if/_config.js b/packages/svelte/tests/compiler-errors/samples/if-block-else-before-else-if/_config.js new file mode 100644 index 0000000000..aec5973c83 --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/if-block-else-before-else-if/_config.js @@ -0,0 +1,9 @@ +import { test } from '../../test'; + +export default test({ + error: { + code: 'block_duplicate_clause', + message: '{:else} cannot appear more than once within a block', + position: [23, 23] + } +}); diff --git a/packages/svelte/tests/compiler-errors/samples/if-block-else-before-else-if/main.svelte b/packages/svelte/tests/compiler-errors/samples/if-block-else-before-else-if/main.svelte new file mode 100644 index 0000000000..5b1e5d559b --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/if-block-else-before-else-if/main.svelte @@ -0,0 +1,7 @@ +{#if a} + A +{:else} + B +{:else if b} + C +{/if}