Hmbown/CodeWhale · error · std::io::Error
path has no parent directory: {}
Error message
path has no parent directory: {} What it means
write_atomic_with_permissions() needs the parent directory of the target path to stage its temp file, but path.parent() returned None because the path is a bare file name or root with no directory component. A generic precondition guard on caller-supplied paths, raised from write_atomic_workspace.
Source
Thrown at crates/tui/src/utils.rs:288
/// (same candidate mode as ordinary `std::fs::write`).
/// - Existing files keep ordinary permission bits (`mode & 0o777`), including
/// executable bits. setuid/setgid/sticky are intentionally not restored.
///
/// On Windows this matches [`write_atomic`] (no POSIX mode simulation).
///
/// # Errors
/// Same failure modes as [`write_atomic`].
pub fn write_atomic_workspace(path: &Path, contents: &[u8]) -> std::io::Result<()> {
write_atomic_with_permissions(path, contents, AtomicWritePermissions::Workspace)
}
fn write_atomic_with_permissions(
path: &Path,
contents: &[u8],
#[cfg_attr(not(unix), allow(unused_variables))] permission_policy: AtomicWritePermissions,
) -> std::io::Result<()> {
let parent = path.parent().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("path has no parent directory: {}", path.display()),
)
})?;
// Capture ordinary rwx bits before replacement. Use symlink_metadata so we
// do not follow links: an inaccessible or dangling symlink target must not
// abort the write — rename still replaces the directory entry, matching
// the pre-#4606 private write_atomic behavior. Symlink entries themselves
// are treated as "no mode to preserve" (new ordinary file after rename);
// only regular-file modes are restored. Mask with 0o777 so setuid/setgid/
// sticky are never restored after rewriting content.
#[cfg(unix)]
let existing_workspace_mode = if permission_policy == AtomicWritePermissions::Workspace {
match fs::symlink_metadata(path) {
Ok(metadata) if metadata.file_type().is_symlink() => None,
Ok(metadata) => {
use std::os::unix::fs::PermissionsExt;View on GitHub (pinned to 0c42157ee5)
Solutions
- Pass an absolute path with a real parent directory
- Join the file name onto an explicit workspace/base directory before writing
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at crates/tui/src/utils.rs:288 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/57279e1edc060388.
Report an issue: GitHub.