nikivdev/code · error

Default home checkout is unsafe for `flow sync`: {state} on

Error message

Default home checkout is unsafe for `flow sync`: {state} on top of {}. Preserve or abandon this child, then `jj edit {}` before retrying.

What it means

`flow sync` rebases the home bookmark, which is unsafe while the working-copy commit sits on the default/home checkout in an anonymous, conflicted, or otherwise dirty state. determine_sync_mode inspects the snapshot (anonymous default-home checkout, conflict, working-copy change count) and bails, telling you to preserve or abandon the child commit and explicitly `jj edit` the home branch before retrying.

Source

Thrown at src/jj.rs:379

struct ResolvedRebaseTarget {
    target: String,
    reason: String,
}

fn determine_sync_mode(snapshot: &WorkflowStatusSnapshot) -> Result<SyncMode> {
    let is_default_home_checkout =
        snapshot.workspace_name == "default" && snapshot.current_role == "home";
    if !is_default_home_checkout {
        return Ok(SyncMode::RebaseCurrentCheckout);
    }
    if anonymous_home_checkout_requires_repair(
        snapshot.current_role,
        snapshot.current_commit_is_anonymous,
        snapshot.current_commit_conflicted,
        snapshot.working_copy_change_count,
    ) {
        let state = anonymous_checkout_label(snapshot.current_commit_conflicted);
        bail!(
            "Default home checkout is unsafe for `flow sync`: {state} on top of {}. Preserve or abandon this child, then `jj edit {}` before retrying.",
            snapshot.current_ref,
            snapshot.home_branch
        );
    }
    Ok(SyncMode::RebaseHomeBookmark {
        home_branch: snapshot.home_branch.clone(),
    })
}

fn build_sync_plan(
    snapshot: &WorkflowStatusSnapshot,
    remote: &str,
    requested_dest: &str,
    resolved_target: &ResolvedRebaseTarget,
    push_bookmark: Option<&str>,
    no_push: bool,
) -> JjSyncPlan {

View on GitHub (pinned to a747e741ae)

Solutions

  1. Run `jj describe -m "wip"` then `jj new` (or `jj squash`) to preserve the child commit, then `jj edit <home-branch>` and retry `flow sync`.
  2. If the child commit is disposable, `jj abandon @` (or restore) and `jj edit <home-branch>` before retrying.
  3. Resolve any conflicts first so current_commit_conflicted is false, then retry.

Example fix

// before
flow sync   # fails: anonymous child on default home checkout
// after
jj describe -m "wip"
jj new
jj edit main
flow sync
Defensive patterns

Strategy: validation

Validate before calling

// shell: refuse to sync when the working copy is dirty or conflicted
jj log -r @ | grep -q conflicted && echo "resolve conflicts first" && exit 1
[ -n "$(jj diff --stat)" ] && echo "commit or abandon working-copy changes first" && exit 1

Try / catch

match flow_sync() {
  Err(e) if e.contains("unsafe for `flow sync`") => {
    jj_describe_and_new();
    jj_edit_home_branch();
    flow_sync()
  }
  r => r,
}

Prevention

When it happens

Trigger: Calling `flow sync` (directly or via build_sync_plan) while the working copy is on an anonymous child of the home branch, the current commit is conflicted, or the working copy has uncommitted changes that make the default home checkout unsafe.

Common situations: Running `flow sync` right after making local edits without a describe/new commit; a conflicted working copy left over from an earlier rebase; being on the raw home checkout instead of a named bookmark after `jj new`.

Related errors


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