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

  1. Use exactly 'BMES' or 'BIO' as constraint_type (uppercase, as implemented).
  2. Convert BIOUL/IOB2 tag sets to one of the supported schemes before requesting transitions.
  3. 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

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


AI-assisted analysis of hankcs/HanLP@ddb1299bdd (2026-08-27). Data as JSON: /api/errors/5a4fcca0b3d0f11d. Report an issue: GitHub.