flxzt/rnote · error

failed to parse height attribute of XoppPage with node id

Error message

failed to parse height attribute of XoppPage with node id {:?}, could not find attribute

What it means

XoppPage::load_from_xml requires a 'height' attribute on the <page> element; when absent the loader returns this error. Width is parsed first, so this fires only for pages that have width but no height.

Solutions

  1. Re-save the file in Xournal++ to restore complete page attributes
  2. Add height="..." to the <page> element matching its width's aspect
  3. Check both width and height attributes exist together when generating xopp files
  4. Validate the document structure before import

Example fix

// before
<page width="793.7">
// after
<page width="793.7" height="1122.52">
Defensive patterns

Strategy: validation

Validate before calling

fn has_required_page_attrs(node: &roxmltree::Node) -> bool {
    node.attributes().any(|a| a.name() == "height")
}

Try / catch

if let Err(e) = page.load_from_xml(node) {
    if e.to_string().contains("height attribute") {
        page.height = DEFAULT_PAGE_HEIGHT; // fallback
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: load_from_xml encountering a <page> node missing 'height' — typically a hand-edited or externally generated .xopp file.

Common situations: Third-party tools emitting partial page definitions; users editing .xopp XML directly and deleting an attribute; malformed export from another app.

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/d8ee46d6d5a1f8f1. Report an issue: GitHub.

Appendix: source

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

    pub layers: Vec<XoppLayer>,
}

impl XmlLoadable for XoppPage {
    fn load_from_xml(&mut self, node: Node) -> anyhow::Result<()> {
        self.width = node
            .attribute("width")
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "failed to parse width attribute of XoppPage for node with id {:?}, could not find attribute",
                    node.id()
                )
            })?
            .parse::<f64>()?;

        self.height = node
            .attribute("height")
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "failed to parse height attribute of XoppPage with node id {:?}, could not find attribute",
                    node.id()
                )
            })?
            .parse::<f64>()?;

        for child in node.children() {
            match child.node_type() {
                NodeType::Element => match child.tag_name().name() {
                    "background" => {
                        self.background.load_from_xml(child)?;
                    }
                    "layer" => {
                        let mut new_layer = XoppLayer::default();
                        new_layer.load_from_xml(child)?;
                        self.layers.push(new_layer);
                    }
                    _ => {}

View on GitHub (pinned to bbc5354502)