flxzt/rnote · error

Failed to get file stem from rnote file

Error message

Failed to get file stem from rnote file "{}"

What it means

export_to_file could not derive the output file stem from the input .rnote file when no explicit stem was supplied. Path::file_stem() returns None for paths ending in '..' or the root, so the command aborts rather than inventing a name.

Solutions

  1. Provide the output file stem explicitly via the CLI argument instead of relying on derivation from the input path
  2. Pass a valid input .rnote file path with a real file name
  3. Sanitize/validate the input path in scripts (reject paths whose file_stem() is None)

Example fix

// before
rnote-cli export --rnote-file ../..
// after
rnote-cli export --rnote-file notes/sketch.rnote --output-file-stem sketch
Defensive patterns

Strategy: validation

Validate before calling

if rnote_file.file_stem().is_none() {
    eprintln!("rnote file path must have a file name/stem");
    std::process::exit(2);
}

Type guard

fn has_stem(p: &Path) -> bool {
    p.file_stem().is_some()
}

Try / catch

match run_result {
    Err(e) if e.to_string().contains("Failed to get file stem") => {
        eprintln!("Pass --output-file-stem or a valid input file path");
    }
    other => other,
}

Prevention

When it happens

Trigger: Running an export command without the optional output file stem argument, with the input rnote_file path being '/', ending in '..', or otherwise having no final path component.

Common situations: Piping a root or relative '..' path into --rnote-file; templated scripts that substitute an empty or degenerate input path.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

        }
        cli::ExportCommand::DocPages {
            output_dir,
            output_file_stem,
            export_format: output_format,
            ..
        } => {
            validators::path_is_dir(output_dir)?;
            // The output file cannot be set with this subcommand
            drop(output_file);

            let pages_export_bytes = engine.export_doc_pages(None).await??;
            let out_ext = output_format.file_ext();
            let output_file_stem = match output_file_stem {
                Some(o) => o.clone(),
                None => match rnote_file.as_ref().file_stem() {
                    Some(stem) => stem.to_string_lossy().to_string(),
                    None => {
                        return Err(anyhow::anyhow!(
                            "Failed to get file stem from rnote file \"{}\"",
                            rnote_file.as_ref().display()
                        ));
                    }
                },
            };
            let pages_amount = pages_export_bytes.len();
            for (page_i, bytes) in pages_export_bytes.into_iter().enumerate() {
                let output_file = doc_page_determine_output_file(
                    page_i,
                    pages_amount,
                    output_dir,
                    &out_ext,
                    &output_file_stem,
                    on_conflict,
                    on_conflict_overwrite,
                )?;
                cli::create_overwrite_file_w_bytes(&output_file, &bytes)

View on GitHub (pinned to bbc5354502)