hankcs/HanLP · error · ValueError
Unknown constraint type: {constraint_type}
Error message
Unknown constraint type: {constraint_type} What it means
allowed_transitions/is_transition_allowed builds legal tag-transition tables for BMES or BIO constraint types. Any constraint_type string other than those two branches falls through to ValueError('Unknown constraint type: ...').
Source
Thrown at hanlp/utils/span_util.py:244
elif constraint_type == "BMES":
if from_tag == "START":
return to_tag in ("B", "S")
if to_tag == "END":
return from_tag in ("E", "S")
return any(
[
# Can only transition to B or S from E or S.
to_tag in ("B", "S") and from_tag in ("E", "S"),
# Can only transition to M-x from B-x, where
# x is the same tag.
to_tag == "M" and from_tag in ("B", "M") and from_entity == to_entity,
# Can only transition to E-x from B-x or M-x, where
# x is the same tag.
to_tag == "E" and from_tag in ("B", "M") and from_entity == to_entity,
]
)
else:
raise ValueError(f"Unknown constraint type: {constraint_type}")
TypedSpan = Tuple[int, Tuple[int, int]]
TypedStringSpan = Tuple[str, Tuple[int, int]]
class InvalidTagSequence(Exception):
def __init__(self, tag_sequence=None):
super().__init__()
self.tag_sequence = tag_sequence
def __str__(self):
return " ".join(self.tag_sequence)
T = str
View on GitHub (pinned to ddb1299bdd)
Solutions
- Use exactly 'BMES' or 'BIO' as constraint_type (uppercase, as implemented).
- Convert BIOUL/IOB2 tag sets to one of the supported schemes before requesting transitions.
- Check for case: lowercase 'bio' will not match.
Example fix
# before
transitions = allowed_transitions('BIOUL', labels)
# after
transitions = allowed_transitions('BMES', labels) Defensive patterns
Strategy: validation
Validate before calling
assert constraint_type in ('BMES', 'BIO'), f'unsupported constraint_type: {constraint_type}' Type guard
def valid_constraint(t):
return t in ('BMES', 'BIO') Prevention
- Define constraint types as module constants.
- Reject unknown config values early with a clear message.
When it happens
Trigger: Calling allowed_transitions('BIOUL', ...) or with a typo/case mismatch ('bio', 'IOB') — the function accepts only the exact strings handled by its if/elif chain (BMES and BIO).
Common situations: Porting AllenNLP code that uses 'BIOUL'; assuming IOB/IOB2 names work; passing config values through without normalizing case.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Unrecognized label encoding {self.label_encoding}
- " ".join(tag_sequence)
- the first two dimensions of emissions and tags must match, g
- mask not supported in SpearmanCorrelation for now.
- Expect X to be 2 or 3 elements but got {repr(X)}
AI-assisted analysis of hankcs/HanLP@ddb1299bdd (2026-08-27).
Data as JSON: /api/errors/5a4fcca0b3d0f11d.
Report an issue: GitHub.