Zackriya-Solutions/meetily · error
Cannot read file: {}
Error message
Cannot read file: {} What it means
validate_audio_file (import.rs:144) wraps the std::fs::metadata error encountered while reading the file's size after the extension gate passed. exists() said true but metadata() failed - the classic TOCTOU window (file vanished between the two syscalls) plus permission and special-file cases. The raw io::Error is embedded, so the suffix distinguishes NotFound, PermissionDenied, and friends.
Source
Thrown at frontend/src-tauri/src/audio/import.rs:144
// Check extension
let extension = path
.extension()
.and_then(|e| e.to_str())
.map(|e| e.to_lowercase())
.unwrap_or_default();
if !AUDIO_EXTENSIONS.contains(&extension.as_str()) {
return Err(anyhow!(
"Unsupported format: .{}. Supported: {}",
extension,
AUDIO_EXTENSIONS.join(", ")
));
}
// Get file size
let metadata = std::fs::metadata(path)
.map_err(|e| anyhow!("Cannot read file: {}", e))?;
let size_bytes = metadata.len();
// Check file size limit
if size_bytes > MAX_FILE_SIZE_BYTES {
return Err(anyhow!(
"File too large: {:.2}GB. Maximum supported size is {}GB",
size_bytes as f64 / (1024.0 * 1024.0 * 1024.0),
MAX_FILE_SIZE_BYTES / (1024 * 1024 * 1024)
));
}
// Get filename without extension for title
let filename = path
.file_stem()
.and_then(|s| s.to_str())
.unwrap_or("Imported Audio")
.to_string();
View on GitHub (pinned to 0281737d87)
Solutions
- Read the io::Error kind in the message: NotFound - re-pick the file; PermissionDenied - fix ownership/ACLs or run outside the sandbox; other kinds - check mount health.
- On Windows, grant Read via file Properties > Security; on macOS, re-pick the file in the current session rather than reusing a stored path.
- Pause sync tools (or wait for placeholder hydration) before importing.
- Retry once after a short delay if the message ends in NotFound - sync tools often release files quickly.
- Long term: replace exists()+metadata() with a single metadata() call, mapping NotFound to the friendlier File-does-not-exist message.
Example fix
// before: two syscalls, file can vanish between them
if !path.exists() { return Err(anyhow!("File does not exist: {}", path.display())); }
let metadata = std::fs::metadata(path).map_err(|e| anyhow!("Cannot read file: {}", e))?;
// after: single syscall, classified errors
let metadata = match std::fs::metadata(path) {
Ok(m) => m,
Err(e) if e.kind() == std::io::ErrorKind::NotFound =>
return Err(anyhow!("File does not exist: {}", path.display())),
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied =>
return Err(anyhow!("Permission denied reading: {}", path.display())),
Err(e) => return Err(anyhow!("Cannot read file: {}", e)),
}; Defensive patterns
Strategy: try-catch
Validate before calling
// Frontend: prove the folder is readable before invoking validation
import { readDir } from '@tauri-apps/plugin-fs';
try { await readDir(dirname(path)); } catch { throw new Error('folder unreadable'); } Try / catch
// Rust: classify the io::Error kind for the user
let metadata = match std::fs::metadata(path) {
Ok(m) => m,
Err(e) if e.kind() == std::io::ErrorKind::NotFound =>
return Err(anyhow!("File does not exist: {}", path.display())),
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied =>
return Err(anyhow!("Permission denied: {}", path.display())),
Err(e) => return Err(anyhow!("Cannot read file: {}", e)),
}; Prevention
- Pause or await cloud-sync hydration before importing from synced folders.
- Ensure the app sandbox retains file access (re-pick per session on macOS).
- Replace exists()+metadata() with a single metadata() call to remove the TOCTOU window.
- Retry once on transient NotFound - AV and sync tools release files quickly.
When it happens
Trigger: File deleted or renamed between the exists() check and the metadata() call (sync tools, antivirus quarantine); no read permission (other-user ownership, Windows ACLs, macOS App Sandbox losing the picked path); a special file (/dev node); a network share that dropped; a Windows path exceeding MAX_PATH without long-path enablement.
Common situations: Importing from cloud-sync folders (OneDrive/Dropbox placeholder dehydration causes metadata races); corporate folder-redirection with strict ACLs; macOS sandboxed builds losing file access after restart (security-scoped bookmark expired); antivirus locking large media files during scan.
Related errors
- Source file not found: {}
- File does not exist: {}
- Unsupported format: .{}. Supported: {}
- File too large: {:.2}GB. Maximum supported size is {}GB
- Failed to create model directory: {}
AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16).
Data as JSON: /api/errors/2c922d3f4f2d77ad.
Report an issue: GitHub.