typst/typst · error · SourceDiagnostic

cyan component

Error message

cyan component

What it means

Typst's cmyk() constructor (crates/typst-library/src/visualize/color.rs:673) requires exactly four ratio components: cyan, magenta, yellow, key/black. The 'cyan component' error comes from args.expect("cyan component") and is raised when the first positional argument is missing or cannot be cast to a ratio component. Unlike rgb(), cmyk() has no hex-string overload; its only alternative form is passing an existing color to convert, e.g. #cmyk(red).

Source

Thrown at crates/typst-library/src/visualize/color.rs:673

        #[external]
        magenta: RatioComponent,
        /// The yellow component.
        #[external]
        yellow: RatioComponent,
        /// The key component.
        #[external]
        key: RatioComponent,
        /// Alternatively: The color to convert to CMYK.
        ///
        /// If this is given, the individual components should not be given.
        #[external]
        color: Color,
    ) -> SourceResult<Color> {
        Ok(Self::Process(ProcessColor::Cmyk(
            if let Some(color) = args.find::<Color>()? {
                color.to_cmyk()
            } else {
                let RatioComponent(c) = args.expect("cyan component")?;
                let RatioComponent(m) = args.expect("magenta component")?;
                let RatioComponent(y) = args.expect("yellow component")?;
                let RatioComponent(k) = args.expect("key/black component")?;
                Cmyk::new(c.get() as f32, m.get() as f32, y.get() as f32, k.get() as f32)
            },
        )))
    }

    /// Create an HSL color.
    ///
    /// This color space is useful for specifying colors by hue, saturation and
    /// lightness. It is also useful for color manipulation, such as saturating
    /// while keeping perceived hue.
    ///
    /// An HSL color is represented internally by an array of four components:
    /// - hue (@angle)
    /// - saturation (@ratio)
    /// - lightness (@ratio)

View on GitHub (pinned to a51e028041)

Solutions

  1. Pass all four components as ratios: #cmyk(27%, 0%, 3%, 5%).
  2. To convert an existing color, pass it as the single argument: #cmyk(rgb("#ff0000")).
  3. If your values are floats, convert them to ratios first: #cmyk(27% or (c * 100)% for components, ...) or multiply by 1% style helpers.
  4. Do not pass a hex string to cmyk(); use #cmyk(rgb("#...")) to go through RGB conversion.

Example fix

// before
#square(fill: cmyk("#ff0000"))

// after
#square(fill: cmyk(0%, 100%, 100%, 0%))
// or convert from an RGB/hex color:
#square(fill: cmyk(rgb("#ff0000")))
Defensive patterns

Strategy: validation

Validate before calling

#let safe-cmyk(vals) = {
  if vals.len() == 4 and vals.all(v => type(v) == ratio) {
    cmyk(..vals)
  } else if vals.len() == 1 and type(vals.first()) == color {
    cmyk(vals.first())
  } else {
    luma(0)
  }
}

Type guard

#let cmyk-input-valid(vals) = (vals.len() == 4 and vals.all(v => type(v) == ratio)) or (vals.len() == 1 and type(vals.first()) == color)

Prevention

When it happens

Trigger: Calling #cmyk() with no arguments; calling #cmyk("#ff0000") (cmyk does not parse hex strings, so the string is neither a Color nor a RatioComponent and the first expect fails); passing a first argument of the wrong type such as #cmyk(0.3, ...) with a plain float instead of a ratio like 30%.

Common situations: Assuming cmyk() accepts hex strings like rgb() does; porting print-shop color specs where values are written as decimals (0.27) instead of Typst ratios (27%); calling cmyk() with keyword arguments only, since components are positional and keywords do not satisfy args.expect.

Related errors


AI-assisted analysis of typst/typst@a51e028041 (2026-08-16). Data as JSON: /api/errors/641e9f4239adbaf0. Report an issue: GitHub.