subframe7536/maple-font · error · ValueError
Font does not have an OS/2 table.
Error message
Font does not have an OS/2 table.
What it means
auto_xheight_capheight() needs the OS/2 table to write sxHeight and sCapHeight. If the TTFont has no 'OS/2' table it raises this ValueError immediately. Fonts produced by very old or minimal toolchains, or some icon/bitmap-derived fonts, may omit OS/2.
Source
Thrown at source/py/task/merge_font/utils.py:179
def _get_glyph_bounds(font, glyph_name):
"""Get (yMin, yMax) of a glyph by name from 'glyf' table."""
glyph_order = font.getGlyphOrder()
if glyph_name not in glyph_order:
raise ValueError(f"Glyph '{glyph_name}' not found in font.")
glyf = font["glyf"]
glyph = glyf[glyph_name]
if glyph.numberOfContours == 0:
# Empty glyph
return (0, 0)
y_min = glyph.yMin
y_max = glyph.yMax
return (y_min, y_max)
def auto_xheight_capheight(font: TTFont):
if "OS/2" not in font:
raise ValueError("Font does not have an OS/2 table.")
if "glyf" not in font:
raise ValueError(
"This script only supports TrueType (glyf) fonts. CFF support not implemented."
)
try:
# Get bounds
z_ymin, z_ymax = _get_glyph_bounds(font, "z")
Z_ymin, Z_ymax = _get_glyph_bounds(font, "Z")
x_height = round(z_ymax) # xHeight = top of lowercase 'z'
cap_height = round(Z_ymax) # capHeight = top of uppercase 'Z'
# Update OS/2 table
os2 = font["OS/2"]
os2.sxHeight = x_height # type: ignore
os2.sCapHeight = cap_height # type: ignore
except Exception as e:View on GitHub (pinned to c08fda97fe)
Solutions
- Add an OS/2 table with fontTools (e.g. copy from a base font or use fontTools.ttLib.newTable('OS/2') and set required fields).
- Regenerate the font from its source with a modern compiler (fontmake/glyphs) so OS/2 is emitted.
- Skip the auto x-height step for such fonts and keep existing OS/2 metrics (or guard the call with `if 'OS/2' in font`).
Example fix
# before
auto_xheight_capheight(font)
# after
if "OS/2" in font:
auto_xheight_capheight(font) Defensive patterns
Strategy: type-guard
Validate before calling
if "OS/2" not in font:
raise RuntimeError("input font lacks OS/2 table; regenerate or add table before polish()") Type guard
def has_required_tables(font, tables=("OS/2", "glyf", "hhea")) -> bool:
return all(t in font for t in tables) Try / catch
try:
auto_xheight_capheight(font)
except ValueError as e:
if "OS/2" in str(e):
font["OS/2"] = newTable("OS/2") # or skip step
else:
raise Prevention
- Sanity-check required tables (OS/2, glyf, hhea, head) on every input font at pipeline start.
- Avoid aggressively stripped fonts; keep standard tables in subsetting.
- Prefer fonts built with modern toolchains that always emit OS/2.
When it happens
Trigger: Calling polish() with a line_height/metrics step that triggers auto_xheight_capheight on a font whose table directory lacks 'OS/2' (font['OS/2'] would KeyError, so the explicit check raises first).
Common situations: Legacy fonts predating OS/2; fonts converted from formats that don't carry OS/2; minimal test/icon fonts; fonts heavily stripped by subsetting tools that dropped the table.
Related errors
- Glyph '{glyph_name}' not found in font.
- This script only supports TrueType (glyf) fonts. CFF support
- No hhea table found.
- No OS/2 table found.
- Original reference width must be positive
AI-assisted analysis of subframe7536/maple-font@c08fda97fe (2026-08-28).
Data as JSON: /api/errors/cd90ece590a8a024.
Report an issue: GitHub.