{"record":{"id":"c23bba3e0c8819e6","repo":"subframe7536/maple-font","slug":"line-height-object-must-contain-ascender-and-de","errorCode":null,"errorMessage":"line_height object must contain 'ascender' and 'descender' fields","messagePattern":"line_height object must contain 'ascender' and 'descender' fields","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"source/py/task/merge_font/utils.py","lineNumber":343,"sourceCode":"            change_line_height(font, line_height_config)\n        elif isinstance(line_height_config, dict):\n            # Object with ascender/descender and optional safe metrics\n            ascender = line_height_config.get(\"top\")\n            descender = line_height_config.get(\"bottom\")\n            safe_ascender = line_height_config.get(\"safe_top\")\n            safe_descender = line_height_config.get(\"safe_bottom\")\n\n            if ascender is not None and descender is not None:\n                change_line_height(\n                    font,\n                    1,\n                    (ascender, descender),\n                    (safe_ascender, safe_descender)\n                    if safe_ascender is not None and safe_descender is not None\n                    else None,\n                )\n            else:\n                raise ValueError(\n                    \"line_height object must contain 'ascender' and 'descender' fields\"\n                )\n        elif isinstance(line_height_config, list) and len(line_height_config) == 2:\n            # Custom [ascender, descender] values\n            change_line_height(\n                font,\n                1,\n                (line_height_config[0], line_height_config[1]),\n                (line_height_config[0], line_height_config[1]),\n            )\n\n    auto_xheight_capheight(font)\n\n    postscript_name = f\"{family_name.replace(' ', '')}-{style_name}\"\n    style_with_prefix_space, style_in_2, style_in_17, is_skip_subfamily, is_italic = (\n        parse_style_name(\n            style_name_compact=style_name,\n        )","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/subframe7536/maple-font/blob/c08fda97fef73d68c1755219852150770f6e6578/source/py/task/merge_font/utils.py#L325-L361","documentation":"polish() accepts line_height either as a dict (requiring 'ascender' and 'descender' keys), a two-element list [ascender, descender], or a number (scale factor). If line_height is a dict (truthy, with more than just a 'factor' path) but lacks both 'ascender' and 'descender' fields, this ValueError is raised.","triggerScenarios":"Config line_height given as an object like {factor: 1.2, typo: true} or {ascender: 1000} (descender missing), or misspelled keys ('Ascender', 'ascent'), reaching the else branch of the dict handling in polish().","commonSituations":"Config typos; YAML/JSON object intended as custom metrics but with one field forgotten; mixing the object form with the factor form incorrectly; schema drift after a config format change.","solutions":["Provide both 'ascender' and 'descender' in the line_height object, or drop to the simple form: line_height: 1.2 (factor) or line_height: [ascender, descender].","Check key spelling and case in the config (exactly 'ascender' and 'descender').","If using a factor, ensure it is parsed as the numeric factor branch, not left as a dict with unrelated keys."],"exampleFix":"# before\nline_height:\n  ascender: 1000   # descender missing\n\n# after\nline_height:\n  ascender: 1000\n  descender: -300","handlingStrategy":"validation","validationCode":"lh = cfg.get(\"line_height\")\nif isinstance(lh, dict):\n    assert \"ascender\" in lh and \"descender\" in lh, \"line_height dict needs both ascender and descender\"","typeGuard":"def is_valid_line_height(lh) -> bool:\n    if isinstance(lh, (int, float)):\n        return True\n    if isinstance(lh, list) and len(lh) == 2:\n        return True\n    return isinstance(lh, dict) and \"ascender\" in lh and \"descender\" in lh","tryCatchPattern":"try:\n    polish(font, config)\nexcept ValueError as e:\n    if \"line_height\" in str(e):\n        print(\"Fix line_height: use factor, [ascender, descender], or {ascender, descender}\")\n    else:\n        raise","preventionTips":["Validate the config schema (allowed line_height forms) before running polish().","Watch for misspelled keys ('ascent' vs 'ascender') in YAML/JSON.","Prefer the simplest form (a numeric factor) unless custom metrics are truly needed."],"tags":["python","config","validation","fonts"],"backgroundTag":"schema-validation-failed","analyzedSha":"c08fda97fef73d68c1755219852150770f6e6578","analyzedAt":"2026-08-28T22:07:29.503Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}