Hmbown/CodeWhale · error · anyhow::Error

could not inspect {}: {error}

Error message

could not inspect {}: {error}

What it means

While locating a workspace .env, Codewhale walks from the current directory up to the git boundary and calls std::fs::symlink_metadata on each candidate .env path. io::ErrorKind::NotFound is treated as 'no .env here' and the walk continues; any other stat error is fatal with 'could not inspect {path}'. The walk only fails when the OS refuses to stat a candidate it can see.

Source

Thrown at crates/tui/src/lib.rs:2466

        return Ok(None);
    };
    load_workspace_dotenv_credentials_from_path(&path).map(Some)
}

fn find_workspace_dotenv() -> Result<Option<PathBuf>> {
    let cwd = std::env::current_dir().context("could not resolve the current workspace")?;
    let boundary = cwd
        .ancestors()
        .find(|ancestor| std::fs::symlink_metadata(ancestor.join(".git")).is_ok())
        .unwrap_or(cwd.as_path());

    for ancestor in cwd.ancestors() {
        let candidate = ancestor.join(".env");
        match std::fs::symlink_metadata(&candidate) {
            Ok(_) => return Ok(Some(candidate)),
            Err(error) if error.kind() == io::ErrorKind::NotFound => {}
            Err(error) => {
                return Err(anyhow!(
                    "could not inspect {}: {error}",
                    candidate.display()
                ));
            }
        }
        if ancestor == boundary {
            break;
        }
    }
    Ok(None)
}

fn load_workspace_dotenv_credentials_from_path(path: &Path) -> Result<WorkspaceDotenvReport> {
    let contents = read_stable_workspace_dotenv(path)?;
    let text = std::str::from_utf8(&contents)
        .map_err(|_| anyhow!("{} is not valid UTF-8", path.display()))?;
    if dotenv_has_variable_expansion(text) {
        bail!(

View on GitHub (pinned to 8880682c63)

Solutions

  1. Run stat <listed-path> as the same user to see the raw errno, then fix permissions (chmod/chown) on that .env or its directory
  2. Remove or rename the unreadable ancestor .env so the walk skips it
  3. Run Codewhale from a directory below the git boundary that does not pass through the bad ancestor
  4. On network filesystems, wait for or repair the mount, then retry
Defensive patterns

Strategy: try-catch

Validate before calling

fn workspace_dotenv_stat_ok(cwd: &std::path::Path) -> std::io::Result<()> {
    let boundary = cwd
        .ancestors()
        .find(|a| std::fs::symlink_metadata(a.join(".git")).is_ok())
        .unwrap_or(cwd.as_path());
    for ancestor in cwd.ancestors() {
        match std::fs::symlink_metadata(ancestor.join(".env")) {
            Ok(_) => {}
            Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
            Err(e) => return Err(e),
        }
        if ancestor == boundary {
            break;
        }
    }
    Ok(())
}

Try / catch

match find_workspace_dotenv(cwd) {
    Ok(found) => found,
    Err(error) if error.to_string().starts_with("could not inspect") => {
        eprintln!("Permission or I/O problem on the listed .env; fix or remove it.");
        return Err(error);
    }
    Err(error) => return Err(error),
}

Prevention

When it happens

Trigger: stat(2) on an ancestor .env returns EACCES/EPERM (no traverse on that directory or no read on the file), EIO from a failing disk or NFS mount, ELOOP from a symlink cycle at directory level, or ESTALE on network filesystems.

Common situations: A parent directory (often $HOME) contains a .env with restrictive ACLs owned by another account; running under a different user or service account; NFS/FUSE mounts returning transient errors; hardened sandboxes that block traversal of parent directories.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/15a6c0ca86286bd4. Report an issue: GitHub.