subframe7536/maple-font · error · Exception
Invalid axe value, range: [{min_value}, {max_value}]
Error message
Invalid axe value, range: [{min_value}, {max_value}] What it means
instantiate() pins a variable font to a static instance. For every axis defined in the font's fvar table it reads the requested value from the axes config (falling back to the axis default) and validates it lies within [minValue, maxValue]. If any configured axis value is out of the font's declared range, this generic Exception is raised.
Source
Thrown at source/py/task/merge_font/utils.py:151
def instantiate(input_font_path: str, output_font_path: str, config: dict) -> None:
"""
Instantiate a variable font with the given configuration.
:param input_font_path: The path to the input font file.
:param output_font_path: The path to the output font file.
:param config: A dictionary containing axis configurations.
"""
f = Font(input_font_path)
coordinates = {}
instance = NamedInstance()
for a in f.t_fvar.table.axes:
axis_tag = a.axisTag
min_value = a.minValue
max_value = a.maxValue
val = config.get(axis_tag, a.defaultValue)
if min_value > val or max_value < val:
raise Exception(f"Invalid axe value, range: [{min_value}, {max_value}]")
coordinates[axis_tag] = val
instance.coordinates = coordinates
static_font, file_base_name = var2static(f, instance)
static_font.save(output_font_path)
static_font.close()
f.close()
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:View on GitHub (pinned to c08fda97fe)
Solutions
- Open the font and check its fvar axes ranges (fonttools ttx -t fvar, or a tool like fontdrop) and set the axis value inside [min, max].
- Clamp the value in code: max(min_value, min(max_value, val)) before calling instantiate.
- Verify the axis tag keys in the config exactly match the font's axis tags (case-sensitive, e.g. 'wght', 'wdth', 'slnt').
Example fix
# before
axes: {wght: 1000} # font range is 100-900
# after
axes: {wght: 900} Defensive patterns
Strategy: validation
Validate before calling
from fontTools.ttLib import TTFont
f = TTFont(font_path)
ranges = {a.axisTag: (a.minValue, a.maxValue) for a in f["fvar"].axes}
for tag, val in axes.items():
lo, hi = ranges[tag]
assert lo <= val <= hi, f"{tag}={val} out of range [{lo}, {hi}]" Type guard
def axis_in_range(val, lo: float, hi: float) -> bool:
return isinstance(val, (int, float)) and lo <= val <= hi Try / catch
try:
instantiate(font_path, out_path, axes)
except Exception as e:
if "Invalid axe value" in str(e):
axes = {t: min(max(v, *sorted(bounds))) for ...} # clamp and retry
else:
raise Prevention
- Dump fvar axes (ttx -t fvar font.ttf) and document valid ranges next to your build config.
- Clamp axis values to [minValue, maxValue] programmatically instead of hardcoding weights.
- Use exact axis tag strings from the font (wght, wdth, slnt) as config keys.
When it happens
Trigger: Passing an 'axes' dict to a font source config where a value for an axis tag (e.g. wght: 1200 when the font supports 100-900, or wght: 50) is below a.minValue or above a.maxValue, or a non-numeric value that breaks the comparison.
Common situations: Copying axis values from one font family to another with different ranges; typos like 'Wght' vs 'wght' matched to the wrong axis; requesting weights (e.g. 950, 1050) a variable font does not expose; passing strings from YAML that compare badly to numbers.
Related errors
- line_height object must contain 'ascender' and 'descender' f
- Glyph '{glyph_name}' not found in font.
- Font does not have an OS/2 table.
- This script only supports TrueType (glyf) fonts. CFF support
- No hhea table found.
AI-assisted analysis of subframe7536/maple-font@c08fda97fe (2026-08-28).
Data as JSON: /api/errors/074d9c89c8b913b8.
Report an issue: GitHub.