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
- Pass all four components as ratios: #cmyk(27%, 0%, 3%, 5%).
- To convert an existing color, pass it as the single argument: #cmyk(rgb("#ff0000")).
- If your values are floats, convert them to ratios first: #cmyk(27% or (c * 100)% for components, ...) or multiply by 1% style helpers.
- 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
- Remember cmyk() accepts no hex strings; convert via #cmyk(rgb("#...")) instead.
- Write CMYK values with explicit % signs - plain floats do not cast to ratio components.
- All four components are mandatory; there is no default like rgb()'s alpha.
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
- magenta component
- yellow component
- hue component
- saturation component
- failed to get JS performance handle
AI-assisted analysis of typst/typst@a51e028041 (2026-08-16).
Data as JSON: /api/errors/641e9f4239adbaf0.
Report an issue: GitHub.