subframe7536/maple-font · error · ValueError
length of `content` ({glyphs_len}) must be equal to length o
Error message
length of `content` ({glyphs_len}) must be equal to length of `target` ({target_len}). What it means
tag_custom() builds custom tag ligature lookups where each source glyph is progressively substituted toward a target pattern; this only works when the source string and target pattern have the same number of characters, since they map 1:1 glyph by glyph. When len(source) != len(target), a positional mapping is impossible and ValueError is raised. This is validated first, before any other target checks.
Source
Thrown at source/py/feature/calt/tag.py:161
- End with one of ["<", ">", "(", ")", "[", "]"]
- Middle characters must be ASCII letters
bg_cls_dict (dict[str, ast.Clazz]): Dictionary mapping uppercase letters to background
class definitions
Returns:
ast.Lookup: A Lookup object containing the substitution rules, named with pattern
"custom_tag_{target middle chars}".
Example:
>>> tag_custom("_TODO_", "(TODO)")
"""
result = []
for source, target in content_list:
glyphs = list(source)
glyphs_len = len(glyphs)
target_len = len(target)
if target_len != glyphs_len:
raise ValueError(
f"length of `content` ({glyphs_len}) must be equal to length of `target` ({target_len})."
)
if target[-1] not in __map:
raise ValueError(
f"Last letter of `target` must in {list(__map.keys())}, current is '{target[-1]}'"
)
# Parse source
source_list = []
for g in glyphs:
if g.isalpha():
source_list.append(f"@{g.upper()}")
else:
source_list.append(ast.gly(g))
# Parse target
target_list = []
for target_gly in target:View on GitHub (pinned to c08fda97fe)
Solutions
- Make source and target exactly the same length — each source glyph maps to one target glyph.
- Pad the source with placeholder glyphs or drop extra target characters to equalize lengths.
- Pre-validate each (source, target) pair with `assert len(source) == len(target)` before calling.
- Split a longer tag into separate same-length tag_custom calls if needed.
Example fix
// before
tag_custom([('_TODO_', '(TODO!)')], bg_cls_dict) # 5 vs 6
// after
tag_custom([('_TODO_', '(TODO)')], bg_cls_dict) # both length 5 Defensive patterns
Strategy: validation
Validate before calling
def validate_tag_pairs(content_list):
for src, tgt in content_list:
if len(src) != len(tgt):
raise ValueError(f'pair {src!r}/{tgt!r}: len {len(src)} != {len(tgt)}')
validate_tag_pairs(content_list)
lookup = tag_custom(content_list, bg_cls_dict) Type guard
def is_equal_length_pair(pair: tuple[str, str]) -> bool:
return len(pair[0]) == len(pair[1]) Try / catch
try:
lookup = tag_custom(content_list, bg_cls_dict)
except ValueError as e:
if 'must be equal to length of' in str(e):
content_list = [(s, t[:len(s)]) for s, t in content_list]
lookup = tag_custom(content_list, bg_cls_dict)
else:
raise Prevention
- Design source and target patterns as strict 1:1 character mappings.
- Unit-test each (source, target) pair for equal length before builds.
- When generating pairs from config, diff source/target lengths in CI.
When it happens
Trigger: Calling tag_custom(content_list=[(src, tgt)], ...) where any tuple has len(src) != len(tgt), e.g. ('_TODO_', '(TODO!)') — source 5 chars vs target 6 chars.
Common situations: Designing a custom tag where the bracket style adds/removes characters relative to the source; typos in the target string; auto-generating pairs from config where source and target were edited independently.
Related errors
- Last letter of `target` must in {list(__map.keys())}, curren
- All tag content must be in ASCII letters or {list(__map.keys
- tag with suffix `:` must be in {built_in_tag_text}, but '{te
- Invalid class_list, must ends with [@Var, @HexLetter]
- id should > 0 and < 100 in Character Variants, current is {i
AI-assisted analysis of subframe7536/maple-font@c08fda97fe (2026-08-28).
Data as JSON: /api/errors/76c0a0bac540c969.
Report an issue: GitHub.