flxzt/rnote · error

ToolStyle try_from:: () for value failed

Error message

ToolStyle try_from::<u32>() for value {} failed

What it means

ToolStyle::try_from(u32) failed because no ToolStyle variant (e.g. verticalspace) matches the given u32 via num_traits::FromPrimitive. The library throws this when a numeric tool-style value, usually restored from persisted settings, is not a valid variant discriminant.

Solutions

  1. Check that the u32 matches a valid ToolStyle discriminant (see toolsconfig.rs).
  2. Fall back to ToolStyle::default() when conversion of loaded settings fails.
  3. Migrate or re-save settings produced by older app versions.

Example fix

// before
let style = ToolStyle::try_from(stored_u32)?;
// after
let style = ToolStyle::try_from(stored_u32)
    .unwrap_or(ToolStyle::default());
Defensive patterns

Strategy: fallback

Validate before calling

fn is_valid_tool_style(v: u32) -> bool {
    ToolStyle::try_from(v).is_ok()
}

Type guard

fn as_tool_style(v: u32) -> Option<ToolStyle> {
    num_traits::FromPrimitive::from_u32(v)
}

Try / catch

let style = ToolStyle::try_from(raw)
    .map_err(|e| log::warn!("{e}; using default"))
    .unwrap_or(ToolStyle::default());

Prevention

When it happens

Trigger: Calling `ToolStyle::try_from(value)` with a u32 outside valid discriminants, e.g. a value from an old settings file after enum changes, or an out-of-range UI tool index.

Common situations: Restoring tool pen configuration across rnote versions; hand-edited config; a GUI dropdown emitting stale indices after the enum gained variants.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08). Data as JSON: /api/errors/48eec3ca0b35e253. Report an issue: GitHub.

Appendix: source

Thrown at crates/rnote-engine/src/pens/pensconfig/toolsconfig.rs:40

    OffsetCamera,
    #[serde(rename = "zoom")]
    Zoom,
    #[serde(rename = "laser")]
    Laser,
}

impl Default for ToolStyle {
    fn default() -> Self {
        Self::VerticalSpace
    }
}

impl TryFrom<u32> for ToolStyle {
    type Error = anyhow::Error;

    fn try_from(value: u32) -> Result<Self, Self::Error> {
        num_traits::FromPrimitive::from_u32(value).ok_or_else(|| {
            anyhow::anyhow!("ToolStyle try_from::<u32>() for value {} failed", value)
        })
    }
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename = "verticalspace_tool_config")]
pub struct VerticalSpaceToolConfig {
    /// horizontal limit
    pub limit_movement_horizontal_borders: bool,
    /// vertical limit
    pub limit_movement_vertical_borders: bool,
}

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(default, rename = "tools_config")]
pub struct ToolsConfig {
    #[serde(rename = "style")]
    pub style: ToolStyle,

View on GitHub (pinned to bbc5354502)