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

  1. 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.
  2. Use input_file.load_bytes_future() and deserialize rnote bytes directly, avoiding the need for a path when path() is None.
  3. Check file.has_uri_scheme("file") / file.path().is_some() in the caller and show a user-facing error to choose a local file.
  4. 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

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


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)