subframe7536/maple-font · error · ValueError

No OS/2 table found.

Error message

No OS/2 table found.

What it means

Companion check in change_line_height(): besides hhea, the 'OS/2' table (usWinAscent/usWinDescent and typo metrics) is required to keep line metrics consistent across platforms. If 'OS/2' is missing the function raises this ValueError.

Source

Thrown at source/py/task/merge_font/utils.py:259

    font: TTFont,
    factor: float = 1.0,
    metric: tuple[float, float] | None = None,
    safe_metric: tuple[float, float] | None = None,
) -> None:
    """
    Adjust the line height of the font by modifying the hhea and OS/2 table.

    Args:
        font: The font to modify
        factor: Scale factor to apply to metrics
        metric: Tuple of (ascender, descender) for custom metrics
        safe_metric: Tuple of (safe_ascender, safe_descender) for safe metrics
    """

    if "hhea" not in font:
        raise ValueError("No hhea table found.")
    if "OS/2" not in font:
        raise ValueError("No OS/2 table found.")

    hhea = font["hhea"]
    os2 = font["OS/2"]

    if metric:
        asc, desc = metric
        safe_asc, safe_desc = safe_metric if safe_metric else (None, None)

        # Maintain original ascender/descender ratio
        ascender_ratio = asc / (asc - desc)  # type: ignore
        # Calculate target total height
        target_total_height = int(round(factor * (asc - desc)))

        # Calculate new metrics
        new_ascender = int(round(target_total_height * ascender_ratio))
        new_descender = new_ascender - target_total_height

        print(f"Change vertical metric to [{new_ascender}, {new_descender}]")

View on GitHub (pinned to c08fda97fe)

Solutions

  1. Add an OS/2 table (fontTools newTable('OS/2'), set version, typo/win metrics) before adjusting line height.
  2. Regenerate the font from a complete source so both hhea and OS/2 exist.
  3. Guard the call to change_line_height with a table-presence check.

Example fix

# before
polish(font)  # line_height set, font lacks OS/2

# after
if "OS/2" in font and "hhea" in font:
    polish(font)
Defensive patterns

Strategy: type-guard

Validate before calling

assert "OS/2" in font, "font must contain OS/2 table for line-height adjustment"

Type guard

def can_change_line_height(font) -> bool:
    return "hhea" in font and "OS/2" in font

Try / catch

try:
    change_line_height(font, metric=(asc, desc))
except ValueError as e:
    if "OS/2" in str(e):
        print("Skipping line-height: font has no OS/2 table")
    else:
        raise

Prevention

When it happens

Trigger: Calling change_line_height (via polish() with line_height config) on a font that has hhea but no OS/2 table.

Common situations: Legacy or stripped fonts missing OS/2; fonts from toolchains that omit OS/2 by default; pipeline earlier stages (like auto_xheight_capheight failing) hinting the same font lacks OS/2.

Related errors


AI-assisted analysis of subframe7536/maple-font@c08fda97fe (2026-08-28). Data as JSON: /api/errors/39559a57af9bc47f. Report an issue: GitHub.