{"record":{"id":"074d9c89c8b913b8","repo":"subframe7536/maple-font","slug":"invalid-axe-value-range-min-value-max-value","errorCode":null,"errorMessage":"Invalid axe value, range: [{min_value}, {max_value}]","messagePattern":"Invalid axe value, range: \\[(.+?), (.+?)\\]","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"source/py/task/merge_font/utils.py","lineNumber":151,"sourceCode":"\ndef instantiate(input_font_path: str, output_font_path: str, config: dict) -> None:\n    \"\"\"\n    Instantiate a variable font with the given configuration.\n\n    :param input_font_path: The path to the input font file.\n    :param output_font_path: The path to the output font file.\n    :param config: A dictionary containing axis configurations.\n    \"\"\"\n    f = Font(input_font_path)\n    coordinates = {}\n    instance = NamedInstance()\n    for a in f.t_fvar.table.axes:\n        axis_tag = a.axisTag\n        min_value = a.minValue\n        max_value = a.maxValue\n        val = config.get(axis_tag, a.defaultValue)\n        if min_value > val or max_value < val:\n            raise Exception(f\"Invalid axe value, range: [{min_value}, {max_value}]\")\n        coordinates[axis_tag] = val\n\n    instance.coordinates = coordinates\n\n    static_font, file_base_name = var2static(f, instance)\n    static_font.save(output_font_path)\n    static_font.close()\n    f.close()\n\n\ndef _get_glyph_bounds(font, glyph_name):\n    \"\"\"Get (yMin, yMax) of a glyph by name from 'glyf' table.\"\"\"\n    glyph_order = font.getGlyphOrder()\n    if glyph_name not in glyph_order:\n        raise ValueError(f\"Glyph '{glyph_name}' not found in font.\")\n    glyf = font[\"glyf\"]\n    glyph = glyf[glyph_name]\n    if glyph.numberOfContours == 0:","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/subframe7536/maple-font/blob/c08fda97fef73d68c1755219852150770f6e6578/source/py/task/merge_font/utils.py#L133-L169","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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')."],"exampleFix":"# before\naxes: {wght: 1000}   # font range is 100-900\n\n# after\naxes: {wght: 900}","handlingStrategy":"validation","validationCode":"from fontTools.ttLib import TTFont\nf = TTFont(font_path)\nranges = {a.axisTag: (a.minValue, a.maxValue) for a in f[\"fvar\"].axes}\nfor tag, val in axes.items():\n    lo, hi = ranges[tag]\n    assert lo <= val <= hi, f\"{tag}={val} out of range [{lo}, {hi}]\"","typeGuard":"def axis_in_range(val, lo: float, hi: float) -> bool:\n    return isinstance(val, (int, float)) and lo <= val <= hi","tryCatchPattern":"try:\n    instantiate(font_path, out_path, axes)\nexcept Exception as e:\n    if \"Invalid axe value\" in str(e):\n        axes = {t: min(max(v, *sorted(bounds))) for ...}  # clamp and retry\n    else:\n        raise","preventionTips":["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."],"tags":["python","fonts","variable-font","validation"],"backgroundTag":"axis-value-out-of-range","analyzedSha":"c08fda97fef73d68c1755219852150770f6e6578","analyzedAt":"2026-08-28T22:07:29.503Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}