can1357/oh-my-pi · error · TouchError

GetFinalPathNameByHandleW failed with code {0}

Error message

GetFinalPathNameByHandleW failed with code {0}

What it means

TouchError::WindowsStdoutPathError is raised only on Windows when the Win32 call GetFinalPathNameByHandleW fails while resolving the final path of an open handle (used by touch's Windows path resolution). The error string carries the GetLastError code. This indicates the OS refused or could not complete final-path resolution for the handle.

Source

Thrown at crates/pi-builtins/src/touch.rs:48

#[cfg(target_os = "linux")]
use uucore::libc;
use uucore::{display::Quotable, parser::shortcut_value_parser::ShortcutValueParser};

use brush_core::{ShellExtensions, builtins::Registration};
use thiserror::Error as ThisError;

use crate::host::{Host, Utility, format_usage, matches_parser, util};

#[derive(Debug, ThisError)]
enum TouchError {
	#[error("Unable to parse date: {0}")]
	InvalidDateFormat(String),
	#[error("Source has invalid access or modification time: {0}")]
	InvalidFiletime(FileTime),
	#[error("failed to get attributes of {}: {}", .0.quote(), io_error(.1))]
	ReferenceFileInaccessible(PathBuf, std::io::Error),
	#[cfg(windows)]
	#[error("GetFinalPathNameByHandleW failed with code {0}")]
	WindowsStdoutPathError(String),
	#[error("{0}")]
	Message(String),
}

fn io_error(error: &std::io::Error) -> String {
	if error.raw_os_error().is_some() {
		match error.kind() {
			ErrorKind::NotFound => "No such file or directory".into(),
			ErrorKind::PermissionDenied => "Permission denied".into(),
			ErrorKind::AlreadyExists => "Already exists".into(),
			ErrorKind::WouldBlock => "Would block".into(),
			_ => error.to_string().split(" (os error ").next().unwrap_or_default().into(),
		}
	} else {
		error.to_string()
	}
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Check the Win32 code in the message and look it up (e.g. ERROR_ACCESS_DENIED=5, ERROR_INVALID_HANDLE=6)
  2. Retry after confirming the target file still exists and is not locked by another process
  3. Run from a process with sufficient privileges for the target location
  4. If on a network/unsupported filesystem, operate on a local path or use path-based (not handle-based) APIs
Defensive patterns

Strategy: fallback

Validate before calling

// Windows-only: confirm target exists and process can open it before touch
#[cfg(windows)]
fn validate_target_windows(path: &std::path::Path) -> Result<(), String> {
    std::fs::metadata(path).map(|_| ()).map_err(|e| e.to_string())
}

Try / catch

match result {
    Err(TouchError::WindowsStdoutPathError(code)) if code == "5" => {
        // ERROR_ACCESS_DENIED: retry elevated or skip path
    }
    Err(TouchError::WindowsStdoutPathError(code)) => {
        eprintln!("final-path resolution failed (code {code}); retrying once");
    }
    other => other.map(|_| ()),
}

Prevention

When it happens

Trigger: On Windows, calling touch code paths that resolve a handle's final path when the handle is invalid, the volume doesn't support the call, the path was deleted mid-operation, or access is denied (non-zero Win32 error code).

Common situations: Touching files on exotic filesystems/network drives that don't support handle-based final path resolution; race where the target file was removed by another process; running with restricted token privileges on Windows.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/fd79948240ceba89. Report an issue: GitHub.