Hmbown/CodeWhale · warning · io::Error

for

Error message

{} for {}: {}

What it means

SnapshotRepo::open_or_init_with_cap (crates/tui/src/snapshot/repo.rs:324) refuses to enable snapshots for workspaces in unsafe locations, checked by `unsafe_workspace_snapshot_reason`. The message starts with the GATE_UNSAFE_LOCATION_MARKER ("workspace snapshots are disabled"), then names the reason and displays the workspace path. The turn loop matches on this marker to show the matching recovery notice.

Solutions

  1. Run codewhale from a real project directory, not $HOME or one of its protected ancestors.
  2. Read the `reason` in the message to see exactly which location rule fired and move the workspace accordingly.
  3. If home detection is wrong (e.g. odd HOME env), fix the environment so effective_home_dir resolves to the real home.
Defensive patterns

Strategy: validation

Validate before calling

let ws = std::fs::canonicalize(cwd)?;
let home = dirs::home_dir().unwrap();
let safe = ws != home && !ws.starts_with(&home) && ws != Path::new("/");

Prevention

When it happens

Trigger: Opening/initing a snapshot repo whose canonicalized work tree is an unsafe location per unsafe_workspace_snapshot_reason — e.g. the workspace is (under) the user's home directory itself, the effective home dir, or another protected system location.

Common situations: Launching codewhale with the working directory set to $HOME or a parent-of-home path; running inside /tmp root or a system dir that the safety gate protects; a mis-set CODEWHALE/effective home making the workspace compare equal to home.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/9a5a8132edc36259. Report an issue: GitHub.

Appendix: source

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

    }

    /// Variant of [`Self::open_or_init`] that accepts an explicit
    /// workspace-size cap. `cap_bytes = 0` disables the cap entirely
    /// (always snapshot, regardless of size).
    ///
    /// When the workspace exceeds the cap and the side repo hasn't
    /// been initialized yet, returns `Err(InvalidInput)` with a
    /// "workspace too large" reason. Subsequent calls (after the user
    /// shrinks the workspace or raises the cap via config) succeed.
    pub fn open_or_init_with_cap(workspace: &Path, cap_bytes: u64) -> io::Result<Self> {
        let work_tree = workspace
            .canonicalize()
            .unwrap_or_else(|_| workspace.to_path_buf());
        if let Some(reason) = unsafe_workspace_snapshot_reason(
            &work_tree,
            crate::config::effective_home_dir().as_deref(),
        ) {
            return Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                format!(
                    "{GATE_UNSAFE_LOCATION_MARKER} for {reason}: {}",
                    display_workspace_for_gate(workspace)
                ),
            ));
        }

        let _ = ensure_snapshot_dir(&work_tree)?;
        let git_dir = snapshot_git_dir(&work_tree);

        let needs_init = !git_dir.exists();
        if needs_init {
            // First-init size guard. Skipping this on subsequent opens
            // 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

View on GitHub (pinned to 73e0f67d83)