flxzt/rnote · error
Could not open file ' ', file path is None.
Error message
Could not open file '{input_file:?}', file path is None. What it means
try_open_file dispatches on the detected FileType. For FileType::RnoteFile the code needs a native filesystem path (for tab de-duplication and saving the origin path), but Gio::File objects can be non-native (e.g. from portal/URI without a path, or fuse handles); when input_file.path() is None this error is thrown.
Solutions
- Ensure the file is a native local path before calling try_open_file; copy non-native files to a temp location and open the copy.
- Use input_file.load_bytes_future() and deserialize rnote bytes directly, avoiding the need for a path when path() is None.
- Check file.has_uri_scheme("file") / file.path().is_some() in the caller and show a user-facing error to choose a local file.
- If launched via CLI with a URI, convert with Gio::File::for_uri only for file:// schemes, otherwise resolve to a local path first.
Example fix
// before
let input_file_path = input_file.path().ok_or_else(|| {
anyhow::anyhow!("Could not open file '{input_file:?}', file path is None.")
})?;
// after
let input_file_path = match input_file.path() {
Some(p) => p,
None => {
// fall back: read bytes and open pathless
let (bytes, _) = input_file.load_bytes_future().await?;
return self.open_rnote_bytes(bytes.to_vec()).map(|_| true);
}
}; Defensive patterns
Strategy: validation
Validate before calling
// rust
if input_file.path().is_none() {
eprintln!("file {:?} has no native path; copy locally before opening", input_file.uri());
} Type guard
fn is_native_file(f: &gio::File) -> bool { f.has_uri_scheme("file") && f.path().is_some() } Try / catch
match appwindow.try_open_file(&file, target_pos, new_tab).await {
Ok(imported) => { /* ... */ }
Err(e) if e.to_string().contains("file path is None") => {
// copy to temp then retry
}
Err(e) => return Err(e),
} Prevention
- Only register file:// paths (not raw URIs) when opening files programmatically
- Copy portal/gvfs-provided files to a temp dir before calling try_open_file
- Check has_uri_scheme("file") in callers that hand files to the app
- For recently-used entries, resolve the real local path first
When it happens
Trigger: Opening an .rnote file whose Gio::File has no backing path — e.g. a file provided as a bare URI (http://, recently-used URI, document portal fd) rather than a native file:// path — via open_file_w_dialogs.
Common situations: Opening files passed by non-native sources: xdg-desktop-portal transfers, some 'recent files' entries, files dragged from remote/virtual locations in the file chooser (e.g. smb/gvfs mounts resolved without path), or CLI args that are URIs.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Could not get a path for file
- ImageMemoryFormat try_from() gdk::MemoryFormat failed…
- No active tab to import into
- Could not retrieve basename for file
- Supplied target file
AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08).
Data as JSON: /api/errors/5f0d1ff8908ddc08.
Report an issue: GitHub.
Appendix: source
Thrown at crates/rnote-ui/src/appwindow/mod.rs:604
.dispatch_toast_error(&gettext("Opening file failed"));
self.overlays().progressbar_abort();
}
}
}
/// Internal method for opening/importing content from a file with a supported content type.
///
/// Returns Ok(true) if file was imported, Ok(false) if not, Err(_) if the import failed.
async fn try_open_file(
&self,
input_file: gio::File,
target_pos: Option<Vector2>,
rnote_file_new_tab: bool,
) -> anyhow::Result<bool> {
let file_imported = match FileType::lookup_file_type(&input_file) {
FileType::RnoteFile => {
let input_file_path = input_file.path().ok_or_else(|| {
anyhow::anyhow!("Could not open file '{input_file:?}', file path is None.")
})?;
// we grab focus
self.present();
// If the file is already opened in a tab, simply switch to it
if let Some(page) = self.tabs_query_file_opened(input_file_path) {
self.overlays().tabview().set_selected_page(&page);
false
} else {
let (rnote_file_new_tab, wrapper) =
match (rnote_file_new_tab, self.active_tab_wrapper()) {
(true, None) => (true, self.new_canvas_wrapper()),
// Create a new tab when the existing is already used
(true, Some(active_wrapper))
if !active_wrapper.canvas().empty()
|| active_wrapper.canvas().output_file().is_some() =>
{
(true, self.new_canvas_wrapper())View on GitHub (pinned to bbc5354502)