Zackriya-Solutions/meetily · warning
File does not exist: {}
Error message
File does not exist: {} What it means
validate_audio_file (import.rs:124) rejects a path because Path::exists() returned false before any format/size checks ran. This is the first guard of audio-file import validation, called when the user picks a file or a path is forwarded programmatically. exists() follows symlinks and returns false for broken links, but in practice the file really is absent by validation time.
Source
Thrown at frontend/src-tauri/src/audio/import.rs:124
pub message: String,
}
/// Check if import is currently in progress
pub fn is_import_in_progress() -> bool {
IMPORT_IN_PROGRESS.load(Ordering::SeqCst)
}
/// Cancel ongoing import
pub fn cancel_import() {
IMPORT_CANCELLED.store(true, Ordering::SeqCst);
}
/// Validate an audio file and return its info using metadata-only approach
/// Falls back to full decode if metadata is unavailable
pub fn validate_audio_file(path: &Path) -> Result<AudioFileInfo> {
// Check file exists
if !path.exists() {
return Err(anyhow!("File does not exist: {}", path.display()));
}
// 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 sizeView on GitHub (pinned to 0281737d87)
Solutions
- Re-open the file via the dialog and pick the current location; simplest and almost always correct.
- If integrating programmatically, canonicalize the path right before invoking and surface the existence check in the UI (disable Import until the file exists).
- For drag-and-drop, resolve the real filesystem path the drop event provides rather than a display path.
- Compare the logged path.display() byte-for-byte with the real path (watch NFC/NFD Unicode normalization on macOS).
- Handle the WebView fake-path case by using the dialog plugin rather than trusting file names.
Example fix
// frontend: before - invoke with whatever string is at hand
await invoke('validate_audio_file', { path: fileNames[0] });
// frontend: after - use the dialog plugin so the OS returns a real absolute path
import { open } from '@tauri-apps/plugin-dialog';
const picked = await open({ multiple: false });
if (picked) await invoke('validate_audio_file', { path: picked }); Defensive patterns
Strategy: validation
Validate before calling
// Frontend: resolve a real absolute path via the dialog before invoking
import { open } from '@tauri-apps/plugin-dialog';
const picked = await open({ multiple: false });
if (!picked) throw new Error('no file selected');
await invoke('validate_audio_file', { path: picked }); Type guard
// TypeScript: reject obviously-invalid candidates before invoke
const looksLikeRealPath = (p: string) =>
p.length > 0 && !p.startsWith('C:\\fake_path') && /\.[a-z0-9]{2,5}$/i.test(p); Try / catch
// Map to a friendly file-moved prompt instead of a raw error
try { await invoke('validate_audio_file', { path }); }
catch (e) {
if (String(e).includes('does not exist')) promptRepickFile();
else throw e;
} Prevention
- Always source paths from the OS dialog plugin, never from copied text or File.name in a WebView.
- Import immediately after picking; do not stage paths across sessions.
- For drag-and-drop, use the drop event's real path payload.
- Watch NFC/NFD Unicode normalization when comparing logged vs actual paths on macOS.
When it happens
Trigger: File deleted/moved between the file-dialog pick and the validate_audio_file invoke; a broken symlink selected via drag-and-drop; the frontend passed a fake-path from a web-style File object (WebView hands back C:\fake_path names); a stale network mount or ejected external drive; a path string mangled by encoding/escaping across the Tauri IPC boundary.
Common situations: User picks from Recent Files but the file was renamed; importing from a USB drive unplugged mid-flow; paths copied from a browser download list after cleanup; non-ASCII/emoji filenames corrupted by shell quoting or JSON escaping.
Related errors
- Unsupported format: .{}. Supported: {}
- File too large: {:.2}GB. Maximum supported size is {}GB
- Source file not found: {}
- Device name cannot be empty
- Cannot read file: {}
AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16).
Data as JSON: /api/errors/142bea57f6cc62ac.
Report an issue: GitHub.