{"record":{"id":"7e4a637001b18b8e","repo":"flxzt/rnote","slug":"failed-to-parse-width-attribute-in-xoppstroke-wi","errorCode":null,"errorMessage":"failed to parse `width` attribute in XoppStroke with node id {:?}, could not find attribute","messagePattern":"failed to parse `width` attribute in XoppStroke with node id (.+?), could not find attribute","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/rnote-engine/src/fileformats/xoppformat.rs","lineNumber":738,"sourceCode":"\n        self.color =\n            XoppColor::from_strokecolor_attr_value(node.attribute(\"color\").ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"failed to parse `color` attribute in XoppStroke with node id {:?}, could not find attribute\",\n                    node.id()\n                )\n            })?)?;\n\n        self.fill = if let Some(fill) = node.attribute(\"fill\") {\n            Some(fill.parse::<i32>()?)\n        } else {\n            None\n        };\n\n        self.width = node\n            .attribute(\"width\")\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"failed to parse `width` attribute in XoppStroke with node id {:?}, could not find attribute\",\n                    node.id()\n                )\n            })?\n            .split(' ')\n            .filter_map(|split| split.parse::<f64>().ok())\n            .collect::<Vec<f64>>();\n\n        self.timestamp = if let Some(_ts) = node.attribute(\"ts\") {\n            // the timestamp parsing is fallible and currently not implemented\n            // ts.parse::<u64>().ok()\n            None\n        } else {\n            None\n        };\n\n        self.audio_filename = node\n            .attribute(\"fn\")","sourceCodeStart":720,"sourceCodeEnd":756,"githubUrl":"https://github.com/flxzt/rnote/blob/bbc5354502ba2fc83eec2670b535348825e679a6/crates/rnote-engine/src/fileformats/xoppformat.rs#L720-L756","documentation":"Thrown by XoppStroke::load_from_xml when a `<stroke>` element has no `width` attribute. Width is required because rnote consumes it (space-separated f64 values) as pressure/width data for the stroke; absence aborts parsing with this error naming the XML node id.","triggerScenarios":"Importing a .xopp file whose `<stroke>` element lacks the `width` attribute, e.g. generated by a script, hand-edited, or produced by a tool writing incomplete stroke definitions.","commonSituations":"Custom xopp generators omitting width; manual XML edits; truncated files where trailing attributes are lost.","solutions":["Add width to the stroke element, e.g. width=\"2.26\" (or the space-separated width list Xournal++ writes).","Regenerate the file with the producer writing width for every stroke.","Re-save the file via Xournal++ to normalize required attributes and retry import."],"exampleFix":"// before (file XML)\n<stroke tool=\"pen\" color=\"black\">...</stroke>\n// after (file XML)\n<stroke tool=\"pen\" width=\"2.26\" color=\"black\">...</stroke>","handlingStrategy":"validation","validationCode":"fn stroke_elements_have_width(xml: &str) -> Result<(), String> {\n    for (i, chunk) in xml.split(\"<stroke\").skip(1).enumerate() {\n        let head = chunk.split('>').next().unwrap_or(\"\");\n        if !head.contains(\"width=\") {\n            return Err(format!(\"stroke #{i} missing `width` attribute\"));\n        }\n    }\n    Ok(())\n}","typeGuard":"fn stroke_attrs_ok(attrs: &[(&str, &str)]) -> bool {\n    attrs.iter().any(|(k, _)| *k == \"width\")\n}","tryCatchPattern":"match import_xopp(path) {\n    Err(e) if e.to_string().contains(\"`width` attribute in XoppStroke\") => {\n        eprintln!(\"A stroke element is missing width; repair XML or re-save in Xournal++: {e:#}\");\n    }\n    Err(e) => eprintln!(\"import failed: {e:#}\"),\n    Ok(doc) => { /* proceed */ }\n}","preventionTips":["Emit width (or width list) for every stroke in generated files","Validate mandatory attributes before import attempts","Avoid hand-trimming XML attributes when shrinking files"],"tags":["parsing","xml","missing-attribute","xopp"],"backgroundTag":"missing-required-argument","analyzedSha":"bbc5354502ba2fc83eec2670b535348825e679a6","analyzedAt":"2026-09-08T13:20:33.747Z","contentChangedAt":"2026-09-08T13:20:33.747Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}