linebender/druid · error
More than one path received for single selection
Error message
More than one path received for single selection
What it means
druid-shell's GTK file dialog can return multiple filenames when multi-selection is enabled in the native chooser. If the dialog was opened with `multi_selection: false` but the chooser still returns more than one file, the API contract (exactly one path for single selection) is broken, so an anyhow error is returned.
Solutions
- Ensure `FileDialogOptions.multi_selection` is correctly propagated when constructing the GTK FileChooser (select_folder/select_file vs select-multiple action)
- Druid (>=0.7/0.8) restricts FileDialog usage to directory selection only — prefer `FileDialog::open_directory` and update code that expects file multi-selection
- Handle the returned Result gracefully (treat like cancellation) and/or filter to the first file if your app can tolerate it
Example fix
// before
let paths: Vec<PathBuf> = dialog.get_paths().unwrap(); // assumes exactly one
// after
match get_file_dialog_path(...) {
Ok(mut paths) if paths.len() == 1 => use(paths.remove(0)),
_ => { /* cancelled or invalid selection */ }
} Defensive patterns
Strategy: validation
Validate before calling
// Validate options and results before use
assert_eq!(options.multi_selection, false);
match paths.len() {
1 => use_path(paths[0].clone()),
_ => cancel(),
} Try / catch
match result { Err(e) if e.to_string().contains("More than one path") => { /* fall back to first path or cancel */ }, other => other } Prevention
- Keep multi_selection option and the GTK chooser mode in sync
- Restrict selection count downstream even when the option is honored
- Prefer druid's open_directory API where multi-selection is unsupported
When it happens
Trigger: Calling FileDialog with multi_selection disabled while the underlying GTK FileChooser is in a state allowing multiple selection (mismatch between druid's `FileDialogOptions` and the constructed chooser widget), then the user selects several files and accepts.
Common situations: Configuring options after the dialog was created or ignoring `multi_selection` when constructing the GTK chooser; user selecting multiple files (Ctrl/Shift-click) in a dialog that should be single-select; version drift where the options flag stopped being honored.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- No path received for filename
- Tried to build a window without setting the handler
- The main thread status has already been claimed by thread
- acquire_input_lock was called on a WinHandler that did not…
- release_input_lock was called on a WinHandler that did not…
AI-assisted analysis of linebender/druid@0f8b1195e4 (2026-09-10).
Data as JSON: /api/errors/cde8315803a58dcd.
Report an issue: GitHub.
Appendix: source
Thrown at druid-shell/src/backend/gtk/dialog.rs:93
if let Some(dt) = &options.default_type {
if !found_default_filter {
tracing::warn!("The default type {:?} is not present in allowed types.", dt);
}
}
}
if let Some(default_name) = &options.default_name {
dialog.set_current_name(default_name);
}
let result = dialog.run();
let result = match result {
ResponseType::Accept => match dialog.filenames() {
filenames if filenames.is_empty() => Err(anyhow!("No path received for filename")),
// If we receive more than one file, but `multi_selection` is false, return an error.
filenames if filenames.len() > 1 && !options.multi_selection => {
Err(anyhow!("More than one path received for single selection"))
}
// If we receive more than one file with a save action, return an error.
filenames if filenames.len() > 1 && action == FileChooserAction::Save => {
Err(anyhow!("More than one path received for save action"))
}
filenames => Ok(filenames.into_iter().map(|p| p.into_os_string()).collect()),
},
ResponseType::Cancel => Err(anyhow!("Dialog was deleted")),
_ => {
tracing::warn!("Unhandled dialog result: {:?}", result);
Err(anyhow!("Unhandled dialog result"))
}
};
// TODO properly handle errors into the Error type
dialog.destroy();
View on GitHub (pinned to 0f8b1195e4)