{"record":{"id":"476dc4dc82d5f0c9","repo":"flxzt/rnote","slug":"affine-does-not-have-value-at-index-0","errorCode":null,"errorMessage":"affine does not have value at index 0","messagePattern":"affine does not have value at index 0","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/rnote-engine/src/fileformats/rnoteformat/maj0min15.rs","lineNumber":140,"sourceCode":"        .remove(\"transform\")\n        .ok_or(anyhow!(\"rect does not contain 'transform'.\"))?;\n    let transform = transform\n        .as_object()\n        .ok_or(anyhow!(\"transform is not a JSON object.\"))?;\n    let affine = transform\n        .get(\"affine\")\n        .ok_or(anyhow!(\"transform does not contain 'affine'.\"))?\n        .as_array()\n        .ok_or(anyhow!(\"affine not an array.\"))?;\n\n    obj.insert(\n        \"affine\",\n        vec![\n            #[allow(clippy::get_first)]\n            affine\n                .get(0)\n                .cloned()\n                .ok_or(anyhow!(\"affine does not have value at index 0\"))?,\n            affine\n                .get(1)\n                .cloned()\n                .ok_or(anyhow!(\"affine does not have value at index 1\"))?,\n            affine\n                .get(3)\n                .cloned()\n                .ok_or(anyhow!(\"affine does not have value at index 3\"))?,\n            affine\n                .get(4)\n                .cloned()\n                .ok_or(anyhow!(\"affine does not have value at index 4\"))?,\n            affine\n                .get(6)\n                .cloned()\n                .ok_or(anyhow!(\"affine does not have value at index 6\"))?,\n            affine\n                .get(7)","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/flxzt/rnote/blob/bbc5354502ba2fc83eec2670b535348825e679a6/crates/rnote-engine/src/fileformats/rnoteformat/maj0min15.rs#L122-L158","documentation":"Thrown when the \"affine\" array has no element at index 0. convert_transform_to_affine_in_obj reads indexes 0,1,3,4,6,7 of the affine matrix (row-major 3x3, last row implicit), and a too-short array cannot supply the required values.","triggerScenarios":"Migrating an .rnote file where the transform's \"affine\" is an array but shorter than 8 elements (empty array fails immediately at index 0).","commonSituations":"Corrupted or hand-truncated JSON, a writer emitting a partial affine matrix, or a copy/paste edit dropping elements.","solutions":["Ensure \"affine\" contains at least 8 elements ([a,b,c,d,e,f,g,h]); a full affine is 8 numbers for a 3x3 with the last row fixed.","Restore the file from backup or re-export it.","Fix the producing code to serialize the complete matrix (e.g. [f64; 8])."],"exampleFix":"// before\n\"affine\": []\n// after\n\"affine\": [1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]","handlingStrategy":"validation","validationCode":"let affine = transform.get(\"affine\").and_then(|a| a.as_array())?;\nif affine.len() < 8 { return Err(format!(\"affine too short: {} of 8 elements\", affine.len())); }","typeGuard":"fn is_full_affine(a: &serde_json::Value) -> bool {\n    a.as_array().map(|a| a.len() >= 8).unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Check affine length before loading files from untrusted sources.","Serialize matrices with fixed-size arrays ([f64; 8]) so short output cannot occur.","Verify file integrity (checksum) after transfer."],"tags":["json","file-migration","index-out-of-range"],"backgroundTag":"index-out-of-bounds","analyzedSha":"bbc5354502ba2fc83eec2670b535348825e679a6","analyzedAt":"2026-09-08T13:20:33.747Z","contentChangedAt":"2026-09-08T13:20:33.747Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}