subframe7536/maple-font · error · TypeError
{g}({type(g)}) is invalid for __gly
Error message
{g}({type(g)}) is invalid for __gly What it means
__gly is the internal glyph serializer that converts any glyph spec (str, list of specs, or Clazz) into FEA text. When it receives a value of any other type (int, None, dict, glyph object, etc.) it raises TypeError naming the value and its type. Since __gly is recursive (lists call __gly per element), a single bad element inside a nested list triggers it.
Source
Thrown at source/py/feature/ast.py:247
__PUNCTUATION_CN_MAP = {
"“": "quotedblleft",
"”": "quotedblright",
"‘": "quoteleft",
"’": "quoteright",
"…": "ellipsis",
"—": "emdash",
}
def __gly(g: str | Clazz | Sequence[str | Clazz] | None) -> str:
if not g:
return ""
if isinstance(g, list):
return " ".join([__gly(_) for _ in g])
if isinstance(g, Clazz):
return g.use()
if not isinstance(g, str):
raise TypeError(f"{g}({type(g)}) is invalid for __gly")
if g in __PUNCTUATION_MAP:
return __PUNCTUATION_MAP[g]
if g in __PUNCTUATION_CN_MAP:
return __PUNCTUATION_CN_MAP[g]
return g
def __prefix(data: str | Clazz | Sequence[str | Clazz] | None) -> str:
if data:
return __gly(data) + " "
return ""
def __suffix(data: str | Clazz | Sequence[str | Clazz] | None) -> str:
if data:
return " " + __gly(data)
return ""
View on GitHub (pinned to c08fda97fe)
Solutions
- Convert the offending value to a str glyph name before passing it (e.g. chr(cp) for codepoints).
- Replace None entries with a valid glyph name or filter them out of lists.
- Wrap glyph objects with .name (or their string form) if you have custom glyph types.
- If you need new supported types, extend __gly in source/py/feature/ast.py rather than passing raw objects.
Example fix
// before ast.subst(None, 65, None, 'space') # 65 is an int // after ast.subst(None, chr(65), None, 'space') # 'A'
Defensive patterns
Strategy: type-guard
Validate before calling
def validate_glyph(g):
if g is None:
raise ValueError('glyph is None — upstream lookup failed')
if not isinstance(g, (str, ast.Clazz, list)):
raise TypeError(f'{g!r} ({type(g).__name__}) must be str, Clazz, or list')
if isinstance(g, list):
for x in g: validate_glyph(x)
validate_glyph(my_glyph)
result = ast.gly(my_glyph) Type guard
def is_glyph_spec(g) -> bool:
if isinstance(g, ast.Clazz) or isinstance(g, str):
return True
return isinstance(g, list) and all(is_glyph_spec(x) for x in g) Try / catch
try:
seq = ast.gly(glyph_spec)
except TypeError as e:
if 'is invalid for __gly' in str(e):
glyph_spec = str(glyph_spec) # or chr(codepoint) / glyph.name
seq = ast.gly(glyph_spec)
else:
raise Prevention
- Convert codepoints to glyph-name strings with chr() before passing.
- Check for None entries after any dynamic glyph lookup — they propagate into __gly.
- Validate config-loaded glyph data (JSON numbers/nulls) at parse time.
When it happens
Trigger: Passing a non-str/non-Clazz value into ast.gly(), ast.subst()/subst_liga() source or target positions, or nesting such a value inside a list passed to those APIs — e.g. None from a failed lookup, an int codepoint, or a parsed glyph object instead of its name string.
Common situations: Reading glyph names from JSON/YAML where values arrive as numbers or null; building glyph lists programmatically and appending None from an earlier failed operation; passing custom glyph objects instead of str.
Related errors
- Invalid class_list, must ends with [@Var, @HexLetter]
- id should > 0 and < 100 in Character Variants, current is {i
- id should > 0 and < 20 in Stylistic Sets, current is {id}
- Invalid item to flatten: {item}
- Unkown feature: {feature.tag}
AI-assisted analysis of subframe7536/maple-font@c08fda97fe (2026-08-28).
Data as JSON: /api/errors/23e9153a6309a5d0.
Report an issue: GitHub.