Skip to content

<svelte:boundary> renders no content if reset is called incorrectly #16134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
swlynch99 opened this issue Jun 12, 2025 · 6 comments
Open

<svelte:boundary> renders no content if reset is called incorrectly #16134

swlynch99 opened this issue Jun 12, 2025 · 6 comments
Labels
awaiting submitter needs a reproduction, or clarification

Comments

@swlynch99
Copy link

swlynch99 commented Jun 12, 2025

Describe the bug

If the reset function is called when the <svelte:boundary> is not showing the failed snippet then nothing within the <svelte:boundary> will be rendered, not the regular content nor the failed snippet.

Original issue description

I have a component which has an inner $derived that occasionally throws an exception. This exception is then handled via a <svelte:boundary> element higher up. The first time the exception is thrown it is properly caught by the boundary. However, after resetting the boundary the exception is no longer handled if thrown again. In fact, nothing gets rendered in that case, not even the failed snippet.

Reproduction

https://svelte.dev/playground/2a0c3ca8ec4a44f396c5cc1bdd65dece?version=5.34.0

Expected behaviour: calling reset should be a no-op or cause the contents of the boundary to be re-rendered. Either behaviour would be fine.

Logs

System Info

System:
    OS: Linux 6.6 Ubuntu 22.04.5 LTS 22.04.5 LTS (Jammy Jellyfish)
    CPU: (18) x64 13th Gen Intel(R) Core(TM) i7-13700H
    Memory: 16.60 GB / 31.18 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 23.11.1 - /usr/bin/node
    Yarn: 1.22.19 - /usr/bin/yarn
    npm: 10.9.2 - /usr/bin/npm
    pnpm: 10.3.0 - /usr/bin/pnpm
  npmPackages:
    svelte: ^5.33.18 => 5.33.18

Severity

annoyance

@brunnerh
Copy link
Member

The logic looks faulty because you call the reset function while not in the error state, though Svelte probably should also handle that differently.

If you do not call the reset function in the valid state, it seems to work as expected.

attr = 3 - attr;
if (reset) {
	reset();
+	reset = null;
}

Playground

@swlynch99
Copy link
Author

The application I originally ran into this issue in does seem to use reset correctly at first glance, though the way the bug manifests is different. Once the playground starts working again I'll take another shot at creating a repro and either update the one here or create a new issue depending on how that goes.

@elliott-with-the-longest-name-on-github
Copy link
Contributor

@swlynch99 playground should be back up -- it got nuked by the GCP outage 😬

@elliott-with-the-longest-name-on-github elliott-with-the-longest-name-on-github added the awaiting submitter needs a reproduction, or clarification label Jun 13, 2025
@swlynch99
Copy link
Author

It seems like the issue I was running into was that errors thrown from stores do not get handled by <svelte:boundary>. I will file a new issue for that and update the description of this one to cover "calling reset incorrectly causes no content to be rendered".

@swlynch99 swlynch99 changed the title <svelte:boundary> fails to catch exceptions after being reset <svelte:boundary> renders no content if reset is called incorrectly Jun 13, 2025
@raythurnvoid
Copy link
Contributor

raythurnvoid commented Jun 15, 2025

@swlynch99 It seems that the current behavior is intended, you are calling reset() in a moment in which Component.svelte throws error synchronously because attr == 2.

It happens only the 3rd time you click because the 1st time you click reset is not valorized yet since the check is perfomed in the button onclick directly that is executed before onerror.

This i what happens step by step:

  1. First click — error is caught

    • attr changes 1 → 2
    • reset not called since it's not set yet
    • "template rendering" was already running, then it throws an error
    • svelte looks up and finds your error boundary
    • onerror is called and the reset function is saved in the state
    • boundary catches it and shows the fallback UI
  2. Second click — reset is called

    • attr changes 2 → 1
    • your handler immediately calls reset()
      • reset() pauses the old "template rendering" (and removes it)
      • It then creates a brand-new "template render" inside the svelte:boundary
    • because attr is now 1, no error is thrown, the UI shows the normal content
  3. Third click — error escapes

    • attr changes 1 → 2 and you call reset() in the same turn
    • reset() again pauses/removes the current "template rendering" and immediately starts creating a fresh one, it means that your Component.svelte is re-mounted
    • during creation the new component throws (attr == 2)
      • the component crashes while still mounting (it hasn’t finished its first run)
      • to avoid an infinite “reset → error → reset…” loop, Svelte lets such mount-time errors bypass the boundary
    • nothing inside the boundary is rendered and the console logs the exception

NOTE: When i say "template rendering" technically i mean BRANCH EFFECT, is a special internal effect that runs inside the svelte:boundary and defines what content is rendered, it's used also for other things like #if

I don't think this is a svelte issue, instead you should not call reset synchronously right after you set the state that will trigger the error, you should call reset only asynchronously when the user clicks a button or if really needed in the onerror but you also must make sure that the state (attr) is also resetted/fixed to prevent errors on components mount.

@swlynch99
Copy link
Author

That sounds reasonable to me. Having a warning printed to the console would have prevented me from getting confused here as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting submitter needs a reproduction, or clarification
Projects
None yet
Development

No branches or pull requests

4 participants