flxzt/rnote · info

Skipped

Error message

Skipped {}

What it means

When the resolved on-conflict policy is `Skip`, `file_conflict_prompt_action` (crates/rnote-cli/src/export.rs:508) returns `Err(anyhow::anyhow!("Skipped {}", output_file.display()))`. This is not a fault: skip is implemented as an error so callers using `?` naturally abort the export of this file, with the path embedded in the message. The string "Skipped <path>" is informational control flow.

Solutions

  1. Inspect the error message: if it starts with `Skipped `, treat the operation as successful and continue with the next file.
  2. Use `--on-conflict suffix` or `--on-conflict overwrite` instead if the existing file should not cause an aborted/blocked result.
  3. In scripts, filter these messages out of the error stream, e.g. only fail on messages that do not begin with "Skipped ".
  4. Library fix: return a typed sentinel (e.g. an enum `ConflictOutcome::Skipped`) instead of encoding skip as an `Err`.
Defensive patterns

Strategy: try-catch

Type guard

fn is_skip_notice(err: &anyhow::Error) -> bool {
    err.to_string().starts_with("Skipped ")
}

Try / catch

match export_to_file(...).await {
    Ok(()) => {/* exported */}
    Err(e) if e.to_string().starts_with("Skipped ") => {
        eprintln!("{e}"); // intentional skip, not a failure
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `get_output_file_path` / `doc_page_determine_output_file` / `export_to_file` for an output path that already exists when `--on-conflict skip` (or `always-skip`, which downgrades to `Skip`) is selected, or the user picks "Skip" in the interactive conflict prompt.

Common situations: Batch-exporting many .rnote files where some outputs already exist from a previous run with `--on-conflict skip`/`--on-conflict always-skip`; scripting where downstream `?`/error handling surfaces these as failures; CI logs showing red "errors" for intentional skips.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08). Data as JSON: /api/errors/5b10ff9f4bbc4da7. Report an issue: GitHub.

Appendix: source

Thrown at crates/rnote-cli/src/export.rs:508

            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 {
        OnConflict::Ask => Err(anyhow::anyhow!(
            "on-conflict behaviour is still Ask after prompting the user."
        )),
        OnConflict::Overwrite => Ok(None),
        OnConflict::Skip => Err(anyhow::anyhow!("Skipped {}", output_file.display())),
        OnConflict::Suffix => {
            let mut i = 0;
            let mut new_path = output_file.to_path_buf();
            let Some(file_stem) = new_path
                .file_stem()
                .map(|s| s.to_string_lossy().to_string())
            else {
                return Err(anyhow::anyhow!("Failed to get file stem"));
            };
            let ext = new_path
                .extension()
                .map(|n| n.to_string_lossy().to_string())
                .unwrap_or_default();
            while new_path.exists() {
                i += 1;
                new_path.set_file_name(format!("{file_stem}_{i}.{ext}"))
            }
            Ok(Some(new_path))

View on GitHub (pinned to bbc5354502)