{"record":{"id":"f7d6d74189f1ec26","repo":"subframe7536/maple-font","slug":"invalid-font-source-type-type-source","errorCode":null,"errorMessage":"Invalid font source type: {type(source)}","messagePattern":"Invalid font source type: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"source/py/task/merge_font/__init__.py","lineNumber":189,"sourceCode":"            temp_path = joinPaths(tmp_dir, temp_filename)\n            instantiate(font_path, temp_path, axes)\n            print(f\"  Instantiated: {temp_path}\")\n            font_path = temp_path\n            result[\"is_temp\"] = True\n        else:\n            # Static font - copy if non-ASCII path\n            if is_ascii_path(font_path):\n                result[\"path\"] = font_path\n            else:\n                print(f\"  Copying non-ASCII path font to tmp: {font_path}\")\n                result[\"path\"] = copy_to_tmp_with_ascii_name(font_path, output_dir)\n                result[\"is_temp\"] = True\n            return result\n\n        result[\"path\"] = font_path\n        return result\n\n    raise ValueError(f\"Invalid font source type: {type(source)}\")\n\n\ndef main(cleanup: bool = False):\n    print(\"Font merge script (Multi-Font Support)\")\n\n    # Load and validate config\n    config_data = load_config()\n    validate_config(config_data)\n\n    family_name = config_data[\"family_name\"]\n    output_dir = config_data[\"output_dir\"]\n    line_height_config = config_data.get(\"line_height\")\n    instances = config_data[\"instances\"]\n\n    # Create directories\n    if not path.exists(output_dir):\n        mkdir(output_dir)\n        print(f\"Created output directory: {output_dir}\")","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/subframe7536/maple-font/blob/c08fda97fef73d68c1755219852150770f6e6578/source/py/task/merge_font/__init__.py#L171-L207","documentation":"prepare_font_source() accepts only two kinds of font sources: a str path to a .ttf/.otf file, or a dict override config with a 'path' key. If `source` is any other Python type (int, list, None, a Path object, etc.) it falls through all isinstance checks and raises this ValueError in main.py:189. It is a defensive type check at the end of the function.","triggerScenarios":"Calling main()/prepare_font_source with a font source entry in the config that is not a string and not a dict — e.g. source is None (YAML key present but empty), a list of paths, a pathlib.Path object, or a number.","commonSituations":"Config file mistakes: a font entry left empty in YAML/JSON (parses to None), accidentally nesting a font under a list, passing pathlib.Path instead of str when calling the function programmatically, or a schema change in the config format.","solutions":["Fix the config so each font source is either a plain path string or an object with a 'path' field.","If calling programmatically, convert pathlib.Path to str(source) before passing it.","Check the printed type in the message to identify which entry has the wrong type, then inspect that config key."],"exampleFix":"# before (config.yaml)\nmainFont:\n  # empty value -> None\n\n# after (config.yaml)\nmainFont:\n  path: fonts/MyFont.ttf","handlingStrategy":"type-guard","validationCode":"src = cfg[\"source\"]\nassert isinstance(src, (str, dict)), f\"font source must be str path or dict, got {type(src)}\"","typeGuard":"def is_valid_font_source(source) -> bool:\n    return isinstance(source, str) or (isinstance(source, dict) and bool(source.get(\"path\")))","tryCatchPattern":"try:\n    prepare_font_source(source, ...)\nexcept ValueError as e:\n    if \"Invalid font source type\" in str(e):\n        print(f\"Fix config font entry: {e}\")\n        sys.exit(1)\n    raise","preventionTips":["Validate the whole config with a schema (jsonschema) before running main().","Avoid empty YAML keys; an empty value parses to None.","Convert pathlib.Path objects to str when calling the API programmatically."],"tags":["python","config","type-error"],"backgroundTag":"invalid-font-source-type","analyzedSha":"c08fda97fef73d68c1755219852150770f6e6578","analyzedAt":"2026-08-28T22:07:29.503Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}