nikivdev/code · warning

sync is blocked

Error message

sync is blocked

What it means

run_sync refuses to run when the computed sync plan is blocked. The plan carries an optional blocked_reason; the error surfaces that reason, or the generic "sync is blocked" when none was recorded. This is a deliberate precondition failure, not an unexpected crash.

Source

Thrown at src/jj.rs:290

    let dest = opts.dest.unwrap_or_else(|| default_branch(&ctx.repo_root));
    let initial_target = resolve_rebase_target(&ctx.workspace_root, &dest, &remote);
    let sync_plan = build_sync_plan(
        &snapshot,
        &remote,
        &dest,
        &initial_target,
        opts.bookmark.as_deref(),
        opts.no_push,
    );
    if opts.plan {
        print_sync_plan(&sync_plan);
        return Ok(());
    }

    jj_run_in(&ctx.workspace_root, &["git", "fetch"])?;
    let target = resolve_rebase_target(&ctx.workspace_root, &dest, &remote);
    let sync_mode = sync_plan.mode.clone().ok_or_else(|| {
        anyhow::anyhow!(
            sync_plan
                .blocked_reason
                .clone()
                .unwrap_or_else(|| "sync is blocked".to_string())
        )
    })?;
    let rebase_args = sync_rebase_args(&sync_mode, &target.target);
    jj_run_owned_in(&ctx.workspace_root, &rebase_args)?;
    if let SyncMode::RebaseHomeBookmark { home_branch } = &sync_mode {
        jj_run_in(
            &ctx.workspace_root,
            &["edit", "--ignore-immutable", home_branch],
        )?;
    }

    // Check for conflicts after rebase
    let has_conflicts = jj_capture_in(
        &ctx.workspace_root,

View on GitHub (pinned to a747e741ae)

Solutions

  1. Read the blocked_reason in the error message (or the generic one) and resolve the stated blocker
  2. Commit or stash uncommitted changes, then rerun sync
  3. Fetch and inspect divergence between local and remote branches
  4. If the reason is unclear, run jj status / jj log to see what state blocks the plan

Example fix

// before
$ jj sync  # -> sync is blocked
// after
$ jj status           # find blocker (dirty workspace / conflicts)
$ jj commit -m "wip"
$ jj sync
Defensive patterns

Strategy: validation

Validate before calling

// before sync
if let Some(reason) = &sync_plan.blocked_reason {
    eprintln!("sync blocked: {reason}");
    std::process::exit(1);
}

Prevention

When it happens

Trigger: Calling `jj sync` (run → run_sync) when sync_plan.mode is None — the planner determined the workspace cannot be synced (e.g. dirty working copy, divergent state, or no valid rebase target after git fetch).

Common situations: Uncommitted changes blocking rebase; conflicts or divergent changes between local and remote; misconfigured remote so resolve_rebase_target can't pick a destination.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/79a9c88586c2cab9. Report an issue: GitHub.