xai-org/grok-build · error · anyhow::Error

worktree not found: {id}

Error message

worktree not found: {id}

What it means

When remove_worktree receives only id_or_path, it calls resolve_worktree_by_id_or_path to map the identifier to a real worktree path. If resolution returns None — the id is unknown, stale, or the path does not correspond to a registered worktree — this error is thrown instead of proceeding.

Source

Thrown at crates/codegen/xai-grok-workspace/src/worktree/mod.rs:1334

    }
}

// ============================================================================
// Remove Worktree
// ============================================================================

pub async fn remove_worktree(
    req: &RemoveWorktreeRequest,
    copy_context: &BackgroundCopyContext,
) -> Result<RemoveWorktreeResponse> {
    let resolved = match (&req.worktree_path, &req.id_or_path) {
        (Some(_), Some(_)) => {
            anyhow::bail!("exactly one of worktreePath or idOrPath must be set, not both")
        }
        (Some(path), None) => path.clone(),
        (None, Some(id)) => match resolve_worktree_by_id_or_path(id)? {
            Some(p) => p.display().to_string(),
            None => anyhow::bail!("worktree not found: {id}"),
        },
        (None, None) => anyhow::bail!("either worktreePath or idOrPath must be set"),
    };
    let worktree_path = Path::new(&resolved);

    tracing::info!(
        target: WORKTREE_LOG,
        path = %resolved,
        force = req.force,
        dry_run = req.dry_run,
        "REMOVE_START: removing worktree"
    );

    // jj workspace: detect by .jj/repo and route to jj-specific cleanup.
    if worktree_path.join(".jj").join("repo").exists() {
        if req.dry_run {
            return Ok(RemoveWorktreeResponse {
                removed: false,

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. List existing worktrees and confirm the exact id_or_path before removing
  2. Remove the worktree by its resolved absolute worktree_path instead of id_or_path
  3. Recreate the worktree (or re-register it) if it was deleted elsewhere and you still need it
  4. Guard the call: resolve_worktree_by_id_or_path first and skip removal when it returns None

Example fix

// before
remove_worktree(&RemoveWorktreeRequest { id_or_path: Some("wt-42".into()), ..Default::default() }, &ctx).await?;
// after
if resolve_worktree_by_id_or_path("wt-42")?.is_some() {
    remove_worktree(&RemoveWorktreeRequest { id_or_path: Some("wt-42".into()), ..Default::default() }, &ctx).await?;
}
Defensive patterns

Strategy: validation

Validate before calling

let resolved = resolve_worktree_by_id_or_path(id)?;
anyhow::ensure!(resolved.is_some(), "worktree {id} does not exist; list worktrees first");

Type guard

fn worktree_exists(id: &str) -> bool {
    resolve_worktree_by_id_or_path(id).map(|r| r.is_some()).unwrap_or(false)
}

Try / catch

match remove_worktree(&req, &ctx).await {
    Err(e) if e.to_string().starts_with("worktree not found") => {
        tracing::warn!("worktree already gone, skipping");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling remove_worktree with id_or_path set to: a worktree id that was already removed, an id that was never created in this workspace, or a path string that no longer matches any registered worktree entry.

Common situations: Stale references after a worktree was removed in another session; typos in ids; passing a repo path that is the main checkout, not a registered worktree; workspace metadata reset or migrated between runs.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/9a92cf89cf5cd20f. Report an issue: GitHub.