flxzt/rnote · error

failed to parse `bottom` attribute in XoppText with node id

Error message

failed to parse `bottom` attribute in XoppText with node id {:?}, could not find attribute

What it means

Thrown when a `<text>` element in a .xopp file has no `bottom` attribute while parsing into XoppText. As with the other bounds errors, the parser refuses text elements without a complete bounding rectangle.

Solutions

  1. Re-save the file with Xournal++ to regenerate all bounds attributes.
  2. Add `bottom="..."` to the `<text>` node with the id shown in the error.
  3. Correct the generating tool so it emits all four bounds attributes.
  4. Pre-validate the xopp XML before import and report the specific missing attribute.

Example fix

// before
<text top="100.0" left="50.0" right="200.0">...</text>
// after
<text top="100.0" left="50.0" right="200.0" bottom="150.0">...</text>
Defensive patterns

Strategy: validation

Validate before calling

// rust
fn text_node_has_bounds(node: &roxmltree::Node) -> bool {
    ["top", "left", "right", "bottom"].iter().all(|a| node.attribute(a).is_some())
}

Type guard

fn get_f64_attr(node: &roxmltree::Node, name: &str) -> Option<f64> {
    node.attribute(name).and_then(|v| v.parse::<f64>().ok())
}

Try / catch

match xopp_file.parse() {
    Ok(doc) => doc,
    Err(e) if e.to_string().contains("`bottom`") => {
        eprintln!(".xopp text node missing 'bottom' attribute: {e}");
    }
}

Prevention

When it happens

Trigger: Importing a .xopp file whose `<text>` node lacks a `bottom` XML attribute.

Common situations: Programmatically generated or hand-edited files missing the bottom coordinate; truncated documents; files from incompatible exporters.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at crates/rnote-engine/src/fileformats/xoppformat.rs:990

            })?
            .parse::<f64>()?;

        // Right
        self.right = node
            .attribute("right")
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "failed to parse `right` attribute in XoppText with node id {:?}, could not find attribute",
                    node.id()
                )
            })?
            .parse::<f64>()?;

        // Bottom
        self.bottom = node
            .attribute("bottom")
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "failed to parse `bottom` attribute in XoppText with node id {:?}, could not find attribute",
                    node.id()
                )
            })?
            .parse::<f64>()?;

        // Data
        if let Some(data) = node.text() {
            self.data = data
                .trim_start_matches([' ', '\n'])
                .trim_end_matches([' ', '\n'])
                .to_string();
        }

        Ok(())
    }
}

View on GitHub (pinned to bbc5354502)