sveltejs/svelte

`lifecycle_outside_component` error in rollup/rolldown SSR build

Opened this issue · 2 comments

Describe the bug

Since svelte@5.39.0, when building a component that uses setContext with Rolldown (or Rollup) for SSR, the build succeeds but the component throws a lifecycle_outside_component error at runtime. This error occurs when trying to render the component server-side with render from svelte/server.

This is a regression that started in Svelte 5.39.0 - downgrading to 5.38.0 resolves the issue.

This was probably introduced in #16748

Reproduction

repo: https://github.com/jackgdll/svelte-5-rolldown-ssr-error

  • install svelte@>=5.39.0
  • create a component that uses setContext
  • bundle it with Rollup or Rolldown
import { defineConfig } from "rolldown";
import svelte from "rollup-plugin-svelte";
import { sveltePreprocess } from "svelte-preprocess";

export default defineConfig({
  input: "src/main.svelte",
  output: {
    file: "dist/rolldown.js",
  },
  plugins: [
    svelte({
      compilerOptions: {
        generate: "server",
      },
      preprocess: sveltePreprocess(),
    }),
  ],
});
  • attempt to render the bundled output with render from svelte/server
  • lifecycle_outside_component error will be thrown

Logs

FAIL  test/ssr.test.js > SSR > renders Rolldown bundled component
Svelte error: lifecycle_outside_component
`setContext(...)` can only be used during component initialisation
https://svelte.dev/e/lifecycle_outside_component
 ❯ lifecycle_outside_component dist/rolldown.js:102:33
    100| function lifecycle_outside_component(name) {
    101|  if (dev_fallback_default) {
    102|   const error = /* @__PURE__ */ new Error(`lifecycle_outside_component\n\`${name}(...)\` can only be used during component initialisation\nhttps://svelte.dev/e/lifecycle_outside_component`);
       |                                 ^
    103|   error.name = "Svelte error";
    104|   throw error;
 ❯ get_or_init_context_map dist/rolldown.js:3405:28
 ❯ setContext dist/rolldown.js:3397:2
 ❯ dist/rolldown.js:3624:3
 ❯ Payload.child node_modules/.pnpm/svelte@5.39.0/node_modules/svelte/src/internal/server/payload.js:112:18
 ❯ Payload.component node_modules/.pnpm/svelte@5.39.0/node_modules/svelte/src/internal/server/payload.js:137:22
 ❯ Main dist/rolldown.js:3623:12
 ❯ Function.#open_render node_modules/.pnpm/svelte@5.39.0/node_modules/svelte/src/internal/server/payload.js:485:3
 ❯ Function.#render node_modules/.pnpm/svelte@5.39.0/node_modules/svelte/src/internal/server/payload.js:346:40
 ❯ Object.value node_modules/.pnpm/svelte@5.39.0/node_modules/svelte/src/internal/server/payload.js:265:48

System Info

System:
    OS: macOS 26.0.1
    CPU: (12) arm64 Apple M2 Max
    Memory: 86.36 MB / 32.00 GB
    Shell: 4.1.2 - /opt/homebrew/bin/fish
  Binaries:
    Node: 22.14.0
    npm: 10.9.2
    pnpm: 10.17.1
  Browsers:
    Firefox: 135.0
    Safari: 26.0.1
  npmPackages:
    rollup: ^4.52.5 => 4.52.5 
    svelte: 5.39.0 => 5.39.0

Severity

blocking an upgrade

This came up in some other issue, but I can't find it right now. Anyway, the problem here is that render needs to bundled together with the rest of your app, because render is reading/writing globals that the compiled code also writes/reads, and so they don't share the same context and then you see the given failure.

The solution is to bundle render with the rest of the app and use the bundled render.

I guess you could do something like

// index.js
export { default as Main } from './main.svelte';
export { render } from 'svelte/server';

Thank you for the workaround, it resolved the error.

Should this be considered a bug or is it a new requirement to bundle render with the component?
If it's the later I can open PR to update the svelte/server docs to mention this.