Hmbown/CodeWhale · error · std::io::Error

snapshot dir has no parent

Error message

snapshot dir has no parent

What it means

InvalidInput returned when snapshot_git_dir(&work_tree).parent() is None, i.e. the computed snapshot git-dir path has no parent component. A normal snapshot dir like <workspace>/.<something> always has the workspace as its parent, so this branch firing means path construction produced a root-equivalent path — an internal invariant violation rather than an expected runtime condition.

Source

Thrown at crates/tui/src/snapshot/repo.rs:271

            // is intentional: paying a workspace walk on every snapshot
            // would defeat the purpose of the cap, and a workspace
            // that fit on first init is allowed to grow within the
            // existing repo's `MAX_SNAPSHOT_SIZE_MB` budget. Users on
            // workspaces that grew past the cap mid-session get the
            // existing aggressive-pruning path in `snapshot()`.
            if estimate_workspace_size_bounded(&work_tree, cap_bytes).is_none() {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidInput,
                    format!(
                        "workspace too large for snapshots (over {} GB of non-excluded content or > {} entries): {}\n  raise `[snapshots] max_workspace_gb` in config.toml (or set it to 0 to disable the cap) if you want snapshots on this workspace.",
                        cap_bytes / (1024 * 1024 * 1024),
                        SIZE_WALK_MAX_ENTRIES,
                        work_tree.display()
                    ),
                ));
            }
            let parent = git_dir.parent().ok_or_else(|| {
                io::Error::new(io::ErrorKind::InvalidInput, "snapshot dir has no parent")
            })?;
            std::fs::create_dir_all(parent)?;
            // `git init` here uses the parent directory as the work tree
            // and stores metadata in `.git`. We then continue to use
            // explicit `--git-dir` / `--work-tree` flags for every other
            // command so behaviour is invariant of cwd.
            let init = crate::dependencies::Git::command()
                .ok_or_else(|| io_other("git not found on PATH"))?
                .arg("init")
                .arg("--quiet")
                .arg(parent)
                .output()
                .map_err(|e| io_other(format!("failed to spawn git init: {e}")))?;
            if !init.status.success() {
                return Err(io_other(format!(
                    "git init failed: {}",
                    String::from_utf8_lossy(&init.stderr).trim()
                )));

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Verify the workspace path you passed is a normal absolute directory, not a root-like path
  2. Check for local modifications to snapshot_git_dir / repo.rs that change the snapshot dir layout
  3. If it reproduces on an unmodified build, capture the exact workspace path and report a bug — this is a defensive invariant
Defensive patterns

Strategy: try-catch

Validate before calling

let ws = workspace.canonicalize().unwrap_or_else(|_| workspace.to_path_buf());
assert!(ws.parent().is_some(), "workspace must not be the filesystem root");

Type guard

fn is_snapshot_dir_invariant(e: &std::io::Error) -> bool {
    e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains("snapshot dir has no parent")
}

Try / catch

match repo::open_or_init_with_cap(&ws, cap) {
    Ok(r) => Ok(r),
    Err(e) if is_snapshot_dir_invariant(&e) => report_bug_with_path(&ws, &e), // not a user-fixable state
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Effectively unreachable through normal API use; would require the workspace canonicalization and snapshot_git_dir to yield a path like "/" (for example a pathological custom workspace path or a regression in snapshot_git_dir).

Common situations: Almost never seen in the wild; appears only with degenerate paths (workspace passed as "/" after canonicalize, which the earlier safety guard at line 238 already rejects) or after a code change to snapshot dir naming.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/951e4ecd5ec7c152. Report an issue: GitHub.