{"record":{"id":"b34592156ac31f24","repo":"flxzt/rnote","slug":"penstyle-try-from-u32-for-value-failed","errorCode":null,"errorMessage":"PenStyle try_from::<u32>() for value {} failed","messagePattern":"PenStyle try_from::<u32>\\(\\) for value (.+?) failed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/rnote-engine/src/pens/mod.rs","lineNumber":226,"sourceCode":"    Eraser,\n    #[serde(rename = \"selector\")]\n    Selector,\n    #[serde(rename = \"tools\")]\n    Tools,\n}\n\nimpl Default for PenStyle {\n    fn default() -> Self {\n        Self::Brush\n    }\n}\n\nimpl TryFrom<u32> for PenStyle {\n    type Error = anyhow::Error;\n\n    fn try_from(value: u32) -> Result<Self, Self::Error> {\n        num_traits::FromPrimitive::from_u32(value)\n            .ok_or_else(|| anyhow::anyhow!(\"PenStyle try_from::<u32>() for value {} failed\", value))\n    }\n}\n\nimpl std::str::FromStr for PenStyle {\n    type Err = anyhow::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        match s {\n            \"brush\" => Ok(Self::Brush),\n            \"shaper\" => Ok(Self::Shaper),\n            \"typewriter\" => Ok(Self::Typewriter),\n            \"eraser\" => Ok(Self::Eraser),\n            \"selector\" => Ok(Self::Selector),\n            \"tools\" => Ok(Self::Tools),\n            s => Err(anyhow::anyhow!(\n                \"Creating PenStyle from &str failed, invalid name {s}\"\n            )),\n        }","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/flxzt/rnote/blob/bbc5354502ba2fc83eec2670b535348825e679a6/crates/rnote-engine/src/pens/mod.rs#L208-L244","documentation":"TryFrom conversion error in PenStyle::try_from::<u32>: the numeric value (typically read from saved settings or file data) has no num_traits FromPrimitive mapping to a PenStyle variant, so the pen style is invalid. Indicates out-of-range or corrupt persisted pen-style discriminants.","triggerScenarios":"TryFrom<u32> for PenStyle with a value outside the valid variant range (e.g. from a settings file edited by hand, or saved by a newer rnote version with more styles).","commonSituations":"Manually edited config files with out-of-range tool indices; downgrading rnote after files recorded newer enum values; corrupted settings storage.","solutions":["Reset the offending setting to a valid pen style (e.g. 0) or delete the settings file to regenerate defaults.","Upgrade rnote so newer style values deserialize correctly.","Add range validation at deserialization time with a fallback to PenStyle::default().","Log the offending value and map unknown indices to the default brush instead of failing."],"exampleFix":"// before\nlet style = PenStyle::try_from(raw_u32)?;\n// after\nlet style = PenStyle::try_from(raw_u32).unwrap_or_default();","handlingStrategy":"fallback","validationCode":"// rust\nfn is_valid_pen_style_u32(v: u32) -> bool {\n    v < (PenStyle::Tools as u32) + 1 // range of defined variants\n}","typeGuard":"fn known_style(v: u32) -> Option<PenStyle> {\n    num_traits::FromPrimitive::from_u32(v)\n}","tryCatchPattern":"let style = PenStyle::try_from(raw_u32)\n    .inspect_err(|e| log::warn!(\"{e}; falling back to default style\"))\n    .unwrap_or_default();","preventionTips":["Never hand-edit numeric enum values in settings files.","Fall back to a default style on deserialization failure.","Handle version upgrades/downgrades of the app gracefully."],"tags":["enum","deserialization","settings"],"backgroundTag":"invalid-enum-value","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"}