vercel/next.js · error

gave up applying effects after {MAX_RETRIES} retries; repeat

Error message

gave up applying effects after {MAX_RETRIES} retries; repeated effect-state divergence on: {keys:?}. This implies multiple routes are fighting to write one of these files.

What it means

Thrown by handle_apply_retry() in turbo-tasks after MAX_RETRIES (4) failed attempts to apply effects because the effect state keeps diverging. Effects are Turbopack's mechanism for persisting side outputs (e.g. written files) during strongly-consistent resolution; persistent divergence means two different computations/routes are repeatedly trying to write the same file(s) with different content.

Source

Thrown at turbopack/crates/turbo-tasks/src/effect.rs:635

/// `MAX_RETRIES`). Returns `Err` for terminal outcomes: a non-`Retry` error, or `Retry` after the
/// retry budget is exhausted.
fn handle_apply_retry(err: EffectsError, attempts: &mut usize) -> Result<()> {
    const MAX_RETRIES: usize = 4; // chosen by a fair dice roll
    match err {
        EffectsError::Retry { keys } if *attempts < MAX_RETRIES => {
            *attempts += 1;
            // Warn on every retry after the first.
            if *attempts > 1 {
                tracing::warn!(
                    attempts = *attempts,
                    ?keys,
                    "retrying effect application; this implies multiple routes are fighting to \
                     write one of these files",
                );
            }
            Ok(())
        }
        EffectsError::Retry { keys } => anyhow::bail!(
            "gave up applying effects after {MAX_RETRIES} retries; repeated effect-state \
             divergence on: {keys:?}. This implies multiple routes are fighting to write one of \
             these files."
        ),
        e => Err(e.into()),
    }
}

/// Build the deduped per-key indices into the captured slice. Detects per-key value-hash
/// conflicts. This is the eager half of effect deduplication — it inspects only the captured
/// effects themselves (no [`EffectStateStorage`] interaction) and is therefore safe to call
/// from inside a turbo-tasks task in [`take_effects`].
fn build_unique_keys(captured: &[Box<dyn CapturedEffect>]) -> UniqueKeys {
    let mut by_key: FxHashMap<Box<[u8]>, usize> = FxHashMap::default();
    for (idx, effect) in captured.iter().enumerate() {
        match by_key.entry(effect.key()) {
            hash_map::Entry::Vacant(entry) => {
                entry.insert(idx);

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Inspect the `keys` in the error to identify which file(s) are being fought over, then find which routes both emit them.
  2. Eliminate the collision: rename/differentiate the conflicting routes or assets so each file has a single producer.
  3. Update to the latest Turbopack/Next.js version — effect-handling bugs are actively fixed.
  4. If the keys are internal build artifacts, simplify the build graph (disable experimental features, reduce conflicting rewrites) to isolate the producer.
Defensive patterns

Strategy: retry

Prevention

When it happens

Trigger: Two or more routes or chunks in a Turbopack build produce conflicting content for the same output file key, so each apply invalidates the other's state and the retry loop never converges within 4 attempts.

Common situations: Multiple pages/app routes accidentally mapped to the same output asset path; a misconfigured manifest or chunk-naming collision; a Turbopack bug in effect deduplication for shared assets; custom output structure causing filename clashes.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/d12c9808cf8ea966. Report an issue: GitHub.