flxzt/rnote · error

Layout try_from:: () for value failed

Error message

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

What it means

Layout implements TryFrom<u32> through num_traits::FromPrimitive; a u32 that maps to no Layout variant triggers this error. It validates numeric layout identifiers (fixed-size, continuous-vertical, semi-infinite, infinite) coming from stored data.

Solutions

  1. Verify the u32 is a valid Layout discriminant before conversion.
  2. Load the document with the rnote version that wrote it, or add a migration mapping old values.
  3. Use the default Layout on failure instead of aborting the load.
  4. Prefer name-based serialization (see Layout::from_str) over raw integers.

Example fix

// before
let layout = Layout::try_from(raw_u32)?;
// after
let layout = Layout::try_from(raw_u32)
    .unwrap_or(Layout::default());
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_layout(v: u32) -> bool {
    Layout::try_from(v).is_ok()
}

Type guard

fn as_layout(v: u32) -> Option<Layout> {
    num_traits::FromPrimitive::from_u32(v)
}

Try / catch

match Layout::try_from(raw) {
    Ok(l) => l,
    Err(_) => {
        log::warn!("unknown layout {raw}; using default");
        Layout::default()
    }
}

Prevention

When it happens

Trigger: Calling Layout::try_from(u32) with an invalid value, typically while deserializing layout preferences from a document or settings store.

Common situations: Files produced by a different rnote version with shifted enum discriminants, corrupted or manually edited files, and external integrations passing raw integers.

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/7c5e2e4b883aac15. Report an issue: GitHub.

Appendix: source

Thrown at crates/rnote-engine/src/document/layout.rs:41

    ContinuousVertical,
    #[serde(rename = "semi_infinite")]
    SemiInfinite,
    #[serde(rename = "infinite")]
    Infinite,
}

impl Default for Layout {
    fn default() -> Self {
        Self::Infinite
    }
}

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

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

impl std::str::FromStr for Layout {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "fixed-size" => Ok(Self::FixedSize),
            "continuous-vertical" => Ok(Self::ContinuousVertical),
            "semi-infinite" => Ok(Self::SemiInfinite),
            "infinite" => Ok(Self::Infinite),
            s => Err(anyhow::anyhow!(
                "Layout from_string failed, invalid name: {s}"
            )),
        }
    }
}

View on GitHub (pinned to bbc5354502)