subframe7536/maple-font · error · TypeError
id should > 0 and < 100 in Character Variants, current is {i
Error message
id should > 0 and < 100 in Character Variants, current is {id} What it means
Character Variants (cvXX) OpenType features are identified by an id 1–99, which the library formats as the tag cv01–cv99. FeatureWithDocs subclasses for Character Variants validate id in __init__ and raise TypeError when the id is out of range, because ids outside 1–99 cannot produce a valid two-digit cv tag. This is a constructor-time constraint, so it fires as soon as the feature object is created.
Source
Thrown at source/py/feature/ast.py:130
self.desc = desc
self.example = example
Feature.__init__(self, tag, content, version)
def desc_item(self):
return f"- [v{self.version}] {self.tag}: {self.desc}"
class CharacterVariant(FeatureWithDocs):
def __init__(
self,
id: int,
desc: str,
content: Clazz | Lookup | Line | list,
version: str,
example: str,
):
if id < 1 or id > 99:
raise TypeError(
f"id should > 0 and < 100 in Character Variants, current is {id}"
)
FeatureWithDocs.__init__(
self,
id=id,
tag=f"cv{id:02d}",
desc=desc,
content=content,
version=version,
example=example,
)
def get_name_lines(self) -> list[Line]:
_name = re.sub(
REGEXP, "", self.desc.replace("`", "").replace(EMPTY_FEAT_SYMBOL, " ")
).strip()
return [
Line("cvParameters {"),View on GitHub (pinned to c08fda97fe)
Solutions
- Set the feature id to an integer in the range 1–99.
- If you need more than 99 variants, split them across additional feature types or reuse/merge existing cv ids.
- Clamp/validate ids from external config before constructing: `if not 1 <= id <= 99: skip or remap`.
Example fix
// before
CharacterVariants(id=100, desc='...', content=..., version='1.0', example='...')
// after
id = 100
assert 1 <= id <= 99, f'cv id must be 1-99, got {id}'
CharacterVariants(id=99, desc='...', content=..., version='1.0', example='...') Defensive patterns
Strategy: validation
Validate before calling
def check_cv_id(id):
if not isinstance(id, int) or not (1 <= id <= 99):
raise ValueError(f'cv id must be int 1-99, got {id}')
check_cv_id(id)
feature = CharacterVariants(id=id, ...) Type guard
def is_valid_cv_id(id) -> bool:
return isinstance(id, int) and 1 <= id <= 99 Try / catch
try:
feature = CharacterVariants(id=id, desc=desc, content=content, version=version, example=example)
except TypeError as e:
if 'Character Variants' in str(e):
logging.error(f'remap cv id {id} into 1-99')
id = min(max(int(id), 1), 99)
feature = CharacterVariants(id=id, desc=desc, content=content, version=version, example=example)
else:
raise Prevention
- Generate cv ids from 1-based enumerations, never raw zero-based loop indices.
- Remember the OpenType cv tag space ends at cv99; plan variants within 99 slots.
- Validate ids from external config before constructing feature objects.
When it happens
Trigger: Constructing a Character Variants feature (any class whose __init__ checks `if id < 1 or id > 99`) with id=0, a negative id, or id >= 100.
Common situations: Using a 0-based index straight from a loop without adding 1; defining cv100 for a 'hundredth' variant not realizing the OpenType cv tag space stops at cv99; loading a config file where ids were serialized off-by-one.
Related errors
- id should > 0 and < 20 in Stylistic Sets, current is {id}
- Invalid class_list, must ends with [@Var, @HexLetter]
- {g}({type(g)}) is invalid for __gly
- 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/97afeddfd72c57f5.
Report an issue: GitHub.