{"record":{"id":"8d8edcd519df3a2b","repo":"flxzt/rnote","slug":"supplied-value-is-not-a-json-object","errorCode":null,"errorMessage":"supplied value is not a JSON object.","messagePattern":"supplied value is not a JSON object\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/rnote-engine/src/fileformats/rnoteformat/maj0min15.rs","lineNumber":120,"sourceCode":"                        .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\n        .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)","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/flxzt/rnote/blob/bbc5354502ba2fc83eec2670b535348825e679a6/crates/rnote-engine/src/fileformats/rnoteformat/maj0min15.rs#L102-L138","documentation":"Thrown at the top of convert_transform_to_affine_in_obj, called from TryFrom<RnoteFileMaj0Min13>::try_from during the maj0min13 -> maj0min15 migration. The helper expects the value passed in (e.g. vectorimage.rectangle or textstroke) to be a JSON object holding a 'transform' key; a non-object value cannot be mutated and triggers this error.","triggerScenarios":"Passing a non-object IValue (string, number, array, bool) as the rect/shape/textstroke node into convert_transform_to_affine_in_obj during file migration.","commonSituations":"Legacy .rnote files whose rectangle/textstroke nodes are scalars or arrays due to corruption, hand edits, or non-conforming exporters.","solutions":["Fix the file JSON so the node passed to the converter is an object with a 'transform' key.","Restore the note from a backup and re-save it in the app.","Add an is_object() check before calling convert_transform_to_affine_in_obj and skip/handle non-objects.","Fix any tooling that generates these nodes to serialize them as objects."],"exampleFix":"// before: assumes obj shape\nconvert_transform_to_affine_in_obj(rect)?;\n// after: guard first\nif !rect.is_object() {\n    anyhow::bail!(\"rectangle node is not an object; file may be corrupt\");\n}\nconvert_transform_to_affine_in_obj(rect)?;","handlingStrategy":"type-guard","validationCode":"if !node.is_object() {\n    return Err(\"transform-bearing node must be an object\".into());\n}","typeGuard":"fn is_object(v: &IValue) -> bool { v.is_object() }","tryCatchPattern":"match convert_transform_to_affine_in_obj(node) {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"supplied value is not a JSON object\") => {\n        // treat file as corrupt; restore backup\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Check is_object() on every node passed to the converter.","Reject non-schema-conforming files at import time.","Keep a raw copy of the file before any migration attempt."],"tags":["json","file-migration","type-mismatch","schema-validation"],"backgroundTag":"schema-validation-failed","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"}