flxzt/rnote · error

"--output-file" and "--output-format" are mutually…

Error message

"--output-file" and "--output-format" are mutually exclusive.

What it means

--output-file and --output-format both specify the export target format, so they cannot be combined. clap's conflicts_with normally prevents this at parse time; this arm is a defensive unreachable fallback in create_doc_export_prefs_from_args that still returns a clear error if both are somehow Some.

Solutions

  1. Keep only one of the two flags: use --output-file <path> (format inferred) or --output-format <fmt>.
  2. If a script adds both, make it choose --output-format when no explicit output path is needed.
  3. If you need both, derive the file path from the format instead (e.g. out.<format>).

Example fix

// before
rnote export doc notes.rnote --output-file out.svg --output-format pdf
// after
rnote export doc notes.rnote --output-format pdf
Defensive patterns

Strategy: validation

Validate before calling

set -- $(echo "$ARGS" | tr ' ' '\n'); c=0; for a in "$@"; do case "$a" in --output-file|--output-format) c=$((c+1));; esac; done; [ "$c" -le 1 ] || { echo "pick one: --output-file or --output-format"; exit 2; }

Prevention

When it happens

Trigger: Passing both --output-file and --output-format to a doc export. Normally blocked by clap conflict validation; reachable only if CLI constraints change or run_export internals are called directly with both set.

Common situations: Scripts that append both flags from separate config sources; manually constructed argument vectors bypassing clap conflicts.

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


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

Appendix: source

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

    no_background: bool,
    no_pattern: bool,
    optimize_printing: bool,
    page_order: SplitOrder,
) -> anyhow::Result<DocExportPrefs> {
    let format = match (output_file, output_format) {
        (Some(file), None) => match file.as_ref().extension().and_then(|ext| ext.to_str()) {
            Some(extension) => doc_export_format_from_ext_str(extension)?,
            None => {
                return Err(anyhow::anyhow!(
                    "The output file \"{}\" needs to have a supported extension to determine its file type.",
                    file.as_ref().display()
                ));
            }
        },
        (None, Some(out_format)) => out_format,
        // should be unreachable because the arguments are exclusive (clap conflicts_with)
        (Some(_), Some(_)) => {
            return Err(anyhow::anyhow!(
                "\"--output-file\" and \"--output-format\" are mutually exclusive."
            ));
        }
        // should be unreachable because either --output-file or --output-format is required
        (None, None) => {
            return Err(anyhow::anyhow!(
                "Either \"--output-file\" or \"--output-format\" is required."
            ));
        }
    };

    let prefs = DocExportPrefs {
        export_format: format,
        with_background: !no_background,
        with_pattern: !no_pattern,
        optimize_printing,
        page_order,
    };

View on GitHub (pinned to bbc5354502)