sveltejs/svelte · error · Error
flush_sync_in_effect
flush_sync_in_effect
Error message
flush_sync_in_effect Cannot use `flushSync` inside an effect https://svelte.dev/e/flush_sync_in_effect
What it means
Thrown when flushSync() is called from inside a running effect. flushSync forces synchronous flush of pending updates; calling it from within an effect that is itself part of the flush cycle would re-enter the flusher and corrupt Svelte's internal batch state, so it is rejected.
Source
Thrown at packages/svelte/src/internal/client/errors.js:263
throw error;
} else {
throw new Error(`https://svelte.dev/e/effect_update_depth_exceeded`);
}
}
/**
* Cannot use `flushSync` inside an effect
* @returns {never}
*/
export function flush_sync_in_effect() {
if (DEV) {
const error = new Error(`flush_sync_in_effect\nCannot use \`flushSync\` inside an effect\nhttps://svelte.dev/e/flush_sync_in_effect`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/flush_sync_in_effect`);
}
}
/**
* Cannot commit a fork that was already discarded
* @returns {never}
*/
export function fork_discarded() {
if (DEV) {
const error = new Error(`fork_discarded\nCannot commit a fork that was already discarded\nhttps://svelte.dev/e/fork_discarded`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/fork_discarded`);
}
}View on GitHub (pinned to 20b341f100)
Solutions
- Remove the flushSync call — by the time the effect runs, scheduling is already managed by Svelte; queue the work via a microtask or $effect instead.
- If you need to ensure updates are applied, use await tick() rather than flushSync.
- Move the flushSync call to an event handler or onMount where no effect is mid-flush.
Example fix
// before
import { flushSync } from 'svelte';
$effect(() => {
flushSync(); // re-entrant flush
measureNode();
});
// after
import { tick } from 'svelte';
$effect(() => {
tick().then(() => measureNode());
}); Defensive patterns
Strategy: validation
Validate before calling
// Do not call flushSync inside an effect. Replace with tick():
import { tick } from 'svelte';
// $effect(() => { tick().then(() => measure()); });
// If you must flush synchronously, do it from an event handler, not an effect. Prevention
- Never call flushSync from inside a $effect, $effect.pre, or $inspect callback.
- Use await tick() for post-update measurement instead.
- If you need synchronous DOM reads after a write, queueMicrotask is safer than flushSync.
When it happens
Trigger: Calling the imported flushSync from 'svelte' (or this lib) directly inside a $effect callback, an $effect.pre, or a function synchronously invoked from one while the effect is flushing. The guard detects re-entrant sync flushing.
Common situations: Calling flushSync to force DOM measurement inside an effect; wrapping test assertions in flushSync within a component effect; porting legacy afterUpdate code that used tick()/flush synchronously into a runes effect.
Related errors
- effect_in_unowned_derived
- effect_orphan
- effect_pending_outside_reaction
- effect_update_depth_exceeded
- get_abort_signal_outside_reaction
AI-assisted analysis of sveltejs/svelte@20b341f100 (2026-08-12).
Data as JSON: /api/errors/f8e390af6975496b.
Report an issue: GitHub.