flxzt/rnote · error
on-conflict behaviour is still Ask after prompting the user.
Error message
on-conflict behaviour is still Ask after prompting the user.
What it means
In rnote-cli's `file_conflict_prompt_action` (crates/rnote-cli/src/export.rs:485), after resolving the on-conflict policy — either from the remembered `on_conflict_overwrite` value or from an interactive dialoguer prompt — the resolved policy is still `OnConflict::Ask`. Since `Ask` is only a placeholder meaning "query the user", reaching the final match with it means the resolution step failed to produce a concrete action (typically because `on_conflict_overwrite` was explicitly seeded with `Some(Ask)`). The function treats this as an internal invariant violation and aborts the export.
Solutions
- Initialize `on_conflict_overwrite` to `None` (or `Some(Overwrite)`/`Some(Skip)`/`Some(Suffix)`) before calling the export functions; never seed it with `OnConflict::Ask`.
- Pass an explicit concrete `--on-conflict` value (e.g. overwrite, skip, suffix) so `Ask` never enters the resolution path.
- If you must keep `Some(Ask)`, ensure the interactive prompt loop runs first (the loop is only entered when `on_conflict_overwrite` is `None`) — remove the pre-seeded value so the user actually gets prompted.
- Library fix: normalize `OnConflict::Ask` to a concrete variant whenever it appears in `on_conflict_overwrite`, or treat `Some(Ask)` as `None` at the top of `file_conflict_prompt_action`.
Example fix
// before let mut on_conflict_overwrite: Option<OnConflict> = Some(OnConflict::Ask); export_to_file(..., on_conflict, &mut on_conflict_overwrite, ...).await?; // after let mut on_conflict_overwrite: Option<OnConflict> = None; // let the prompt resolve Ask export_to_file(..., on_conflict, &mut on_conflict_overwrite, ...).await?;
Defensive patterns
Strategy: validation
Validate before calling
// Before invoking the export API, never seed the memo with Ask:
let mut on_conflict_overwrite: Option<OnConflict> = match on_conflict {
OnConflict::Ask => None, // let the interactive prompt resolve it
other => Some(other),
};
if output_file.exists() && on_conflict_overwrite == Some(OnConflict::Ask) {
anyhow::bail!("--on-conflict ask cannot be pre-selected; use overwrite|skip|suffix");
} Type guard
fn is_concrete_conflict_policy(p: &OnConflict) -> bool {
!matches!(p, OnConflict::Ask | OnConflict::AlwaysOverwrite | OnConflict::AlwaysSkip | OnConflict::AlwaysSuffix)
} Prevention
- Initialize on_conflict_overwrite to None, never Some(Ask).
- Require an explicit concrete --on-conflict value in non-interactive/CI runs.
- Write a unit test asserting the prompt loop resolves Ask into a concrete variant.
When it happens
Trigger: Calling `get_output_file_path` or `doc_page_determine_output_file` for a target path that already exists while `on_conflict_overwrite` is `Some(OnConflict::Ask)` (a stale/incorrectly-initialized memoized value), so the prompt loop at line 456 (`while matches!(on_conflict, OnConflict::Ask)`) is skipped entirely and the first match at line 483 sees `Ask`.
Common situations: Programmatic/embedded use of the CLI export API where the `on_conflict_overwrite` out-parameter was initialized to `Some(Ask)` instead of `None`; state carried over from a previous session where the user was never asked; running in a non-interactive environment combined with a hand-built `OnConflict` value that a user would normally never select via `--on-conflict`.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Failed to get filename from the supplied file
- There must be at least one rnote file specified for…
- The option "--file-stem" cannot be used when exporting…
- Expected only a single rnote file. The option…
- The output file " " needs to have a supported extension to…
AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08).
Data as JSON: /api/errors/3f15bb1f1132c3b8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/rnote-cli/src/export.rs:485
))
.items(options)
.default(1)
.interact()
{
Ok(0) => cli::open_file_default_app(output_file)?,
Ok(c) => on_conflict = options[c],
Err(e) => {
return Err(anyhow::anyhow!(
"Failed to show select prompt, retry or select the behavior with\"--on-conflict\", Err: {e:?}"
));
}
};
}
}
};
match on_conflict {
OnConflict::Ask => {
return Err(anyhow::anyhow!(
"on-conflict behaviour is still Ask after prompting the user."
));
}
OnConflict::AlwaysOverwrite => {
on_conflict = OnConflict::Overwrite;
*on_conflict_overwrite = Some(on_conflict);
}
OnConflict::AlwaysSkip => {
on_conflict = OnConflict::Skip;
*on_conflict_overwrite = Some(on_conflict);
}
OnConflict::AlwaysSuffix => {
on_conflict = OnConflict::Suffix;
*on_conflict_overwrite = Some(on_conflict);
}
OnConflict::Overwrite | OnConflict::Skip | OnConflict::Suffix => (),
}
match on_conflict {View on GitHub (pinned to bbc5354502)