hatoo/oha · error · anyhow::Error
Failed to read file
Error message
Failed to read file '{}': {} What it means
I/O failure raised by FormPart::from_str when the -F value uses the '@filename' or '<filename' file-upload form but the file cannot be opened and read (file does not exist, insufficient permissions, or it is a directory). The '{}' placeholders carry the path and the underlying io::Error.
Solutions
- Verify the path is correct and the file exists (ls / realpath).
- Check read permissions on the file and on every directory in its path.
- Ensure the target is a regular file, not a directory or special device.
- If the path may be relative, confirm the process's current working directory.
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at src/curl_compat.rs:121 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of hatoo/oha@4efba2d113 (2026-09-09).
Data as JSON: /api/errors/8d2cf5cef587c607.
Report an issue: GitHub.
Appendix: source
Thrown at src/curl_compat.rs:121
.ok_or_else(|| anyhow::anyhow!("Invalid form format: missing '=' in '{}'", s))?;
let name = name.to_string();
// Parse the value part which may contain semicolon-separated options
let parts: Vec<&str> = rest.split(';').collect();
let value_part = parts[0];
let mut filename = None;
let mut content_type = None;
let data;
// Check if this is a file upload (@filename or <filename)
if let Some(file_path) = value_part.strip_prefix('@') {
// Remove '@' prefix
// Read file content
data = std::fs::read(file_path)
.map_err(|e| anyhow::anyhow!("Failed to read file '{}': {}", file_path, e))?;
// Extract filename from path
filename = std::path::Path::new(file_path)
.file_name()
.and_then(|name| name.to_str())
.map(|s| s.to_string());
} else if let Some(file_path) = value_part.strip_prefix('<') {
// Remove '<' prefix
// Read file content
data = std::fs::read(file_path)
.map_err(|e| anyhow::anyhow!("Failed to read file '{}': {}", file_path, e))?;
// Do not set filename for '<' format (curl behavior)
} else {
// Regular form field with string value
data = value_part.as_bytes().to_vec();
}View on GitHub (pinned to 4efba2d113)