{"record":{"id":"5ac28ee2199f195a","repo":"flxzt/rnote","slug":"could-not-get-a-path-for-file-file","errorCode":null,"errorMessage":"Could not get a path for file: `{file:?}`.","messagePattern":"Could not get a path for file: `(.+?)`\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/rnote-ui/src/canvas/imexport.rs","lineNumber":229,"sourceCode":"    /// Saves the document to the given file.\n    ///\n    /// Returns:\n    /// - `Ok(true)` if saving was successful\n    /// - `Ok(false)` if a save was already in progress (and thus this function didn't do anything)\n    /// - `Err(e)` when saving failed in any way\n    #[tracing::instrument(skip_all, fields(path = format!(\"{:?}\", file.path())))]\n    pub(crate) async fn save_document_to_file(&self, file: &gio::File) -> anyhow::Result<bool> {\n        // skip saving when it is already in progress\n        if self.save_in_progress() {\n            debug!(\"Returning early, saving file is already in progress\");\n            return Ok(false);\n        }\n        self.set_save_in_progress(true);\n        debug!(\"Saving file is now in progress\");\n\n        let filepath = file.path().ok_or_else(|| {\n            self.set_save_in_progress(false);\n            anyhow::anyhow!(\"Could not get a path for file: `{file:?}`.\")\n        })?;\n        let basename = file.basename().ok_or_else(|| {\n            self.set_save_in_progress(false);\n            anyhow::anyhow!(\"Could not retrieve basename for file: `{file:?}`.\")\n        })?;\n        let rnote_bytes_receiver = self\n            .engine_ref()\n            .save_as_rnote_bytes(basename.to_string_lossy().to_string());\n\n        let mut skip_set_output_file = false;\n        if let Some(output_filepath) = self.output_file().and_then(|f| f.path())\n            && crate::utils::paths_abs_eq(output_filepath, &filepath).unwrap_or(false)\n        {\n            skip_set_output_file = true;\n        }\n\n        self.dismiss_output_file_modified_toast();\n","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/flxzt/rnote/blob/bbc5354502ba2fc83eec2670b535348825e679a6/crates/rnote-ui/src/canvas/imexport.rs#L211-L247","documentation":"save_document_to_file writes the document to a user-chosen Gio::File. The writer needs a real filesystem path (and basename) to serialize to; when the chosen File has no path (non-native location such as a portal handle or unusual URI), path() is None, save-in-progress is reset, and this error is thrown.","triggerScenarios":"dialog_save_doc_as -> save_document_to_file with a File chosen from a non-native source (gvfs/network location, document portal fd, URI without file:// scheme) where file.path() returns None.","commonSituations":"Saving via flatpak document portal into odd locations; picking an MTP/phone or network share target in the save dialog whose Gio::File has no native path; passing a constructed URI instead of a local path to the save API.","solutions":["Choose a native local directory in the save dialog (local filesystem path), then move/copy the saved file to remote targets afterwards.","In the caller, check file.path().is_some() before invoking save_document_to_file and fall back to load_bytes + temp-file write + copy for pathless files.","Use file.load_bytes()/create-on-temp then gio copy into the destination File instead of requiring a direct path."],"exampleFix":"// before\nlet filepath = file.path().ok_or_else(|| {\n    self.set_save_in_progress(false);\n    anyhow::anyhow!(\"Could not get a path for file: `{file:?}`.\")\n})?;\n// after\nlet Some(filepath) = file.path() else {\n    self.set_save_in_progress(false);\n    anyhow::bail!(\n        \"Cannot save to non-native location {file:?}; pick a local folder.\"\n    );\n};","handlingStrategy":"validation","validationCode":"// rust\nif file.path().is_none() {\n    eprintln!(\"target {:?} has no native path; choose a local folder or copy the result\", file.uri());\n}","typeGuard":"fn is_native_target(f: &gio::File) -> bool { f.path().is_some() }","tryCatchPattern":"match canvas.save_document_to_file(&file, ...).await {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"Could not get a path\") => {\n        // save to temp file, then gio copy into `file`\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Configure the save dialog to local folders, or handle remote targets via copy-from-temp","Always reset save_in_progress on early error returns (the code does; keep that pattern)","For flatpak, be aware portal-picked files may be pathless — test save flows in sandbox","If you must support remote targets, implement bytes -> temp file -> gio File::copy"],"tags":["gio","file-path","save","glib"],"backgroundTag":"invalid-url-format","analyzedSha":"bbc5354502ba2fc83eec2670b535348825e679a6","analyzedAt":"2026-09-08T13:20:33.747Z","contentChangedAt":"2026-09-08T13:20:33.747Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}