{"record":{"id":"b822c22e22397eac","repo":"flxzt/rnote","slug":"bitmapimage-does-not-contain-rectangle","errorCode":null,"errorMessage":"bitmapimage does not contain 'rectangle'.","messagePattern":"bitmapimage does not contain 'rectangle'\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/rnote-engine/src/fileformats/rnoteformat/maj0min15.rs","lineNumber":103,"sourceCode":"                .get_mut(\"bitmapimage\")\n            {\n                let bitmapimage = bitmapimage\n                    .as_object_mut()\n                    .ok_or(anyhow!(\"bitmapimage is not a JSON object.\"))?;\n\n                convert_transform_to_affine_in_obj(\n                    bitmapimage\n                        .get_mut(\"image\")\n                        .ok_or(anyhow!(\"bitmapimage does not contain 'image'.\"))?\n                        .as_object_mut()\n                        .ok_or(anyhow!(\"image is not a JSON object.\"))?\n                        .get_mut(\"rectangle\")\n                        .ok_or(anyhow!(\"image does not contain 'rectangle'.\"))?,\n                )?;\n                convert_transform_to_affine_in_obj(\n                    bitmapimage\n                        .get_mut(\"rectangle\")\n                        .ok_or(anyhow!(\"bitmapimage does not contain 'rectangle'.\"))?,\n                )?;\n            }\n        }\n\n        //dbg!(&value);\n\n        Ok(Self {\n            engine_snapshot: value.engine_snapshot,\n        })\n    }\n}\n\n/// Converts a \"object->transform->nalgebra-affine\" to \"object->(glamx-)affine\"\nfn convert_transform_to_affine_in_obj(obj: &mut IValue) -> anyhow::Result<()> {\n    let obj = obj\n        .as_object_mut()\n        .ok_or(anyhow!(\"supplied value is not a JSON object.\"))?;\n    let transform = obj","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/flxzt/rnote/blob/bbc5354502ba2fc83eec2670b535348825e679a6/crates/rnote-engine/src/fileformats/rnoteformat/maj0min15.rs#L85-L121","documentation":"Thrown in TryFrom<RnoteFileMaj0Min13>::try_from when a bitmapimage stroke object lacks the top-level 'rectangle' key. After converting image.rectangle, the migration also converts bitmapimage.rectangle itself to the new affine format; a missing rectangle fails the maj0min13 -> maj0min15 upgrade.","triggerScenarios":"Migrating maj0min13 -> maj0min15 with stroke_components[*].value.bitmapimage missing its 'rectangle' field.","commonSituations":"Hand-edited or truncated legacy .rnote files; third-party exporters that omit the rectangle placement metadata.","solutions":["Restore the 'rectangle' object on bitmapimage in the file JSON, including its legacy 'transform'.","Recover the note from a backup and re-save it through the app.","Pre-validate the file with the maj0min13 schema (require bitmapimage.rectangle) before migrating.","Patch the migration to skip bitmap strokes without rectangle with a warning."],"exampleFix":"// before\n.ok_or(anyhow!(\"bitmapimage does not contain 'rectangle'.\"))?\n// after\nif let Some(rect) = bitmapimage.get_mut(\"rectangle\") {\n    convert_transform_to_affine_in_obj(rect)?;\n} else {\n    log::warn!(\"bitmapimage.rectangle missing; skipped\");\n}","handlingStrategy":"validation","validationCode":"let bi = &comp[\"value\"][\"bitmapimage\"];\nif bi.is_object() && bi.get(\"rectangle\").is_none() {\n    return Err(\"bitmapimage missing 'rectangle'\".into());\n}","typeGuard":"fn bitmapimage_has_rectangle(v: &IValue) -> bool {\n    v.get(\"bitmapimage\")\n        .and_then(|b| b.get(\"rectangle\"))\n        .map_or(false, |r| r.is_object())\n}","tryCatchPattern":null,"preventionTips":["Validate the full bitmapimage shape (image + rectangle) before migration.","Use the app's own save path to produce files; avoid manual edits.","Recover from backups rather than patching corrupt JSON by hand."],"tags":["json","file-migration","missing-key","schema-validation"],"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"}