hankcs/HanLP · error · ValueError

Invalid encoding {encoding} passed to 'to_bioul'.

Error message

Invalid encoding {encoding} passed to 'to_bioul'.

What it means

ValueError from to_bioul, a scheme converter that only understands source encodings 'IOB1' and 'BIO'. Passing any other string (e.g. 'IOB2', 'BIOUL', 'iob1' lowercase, or a typo) is rejected.

Source

Thrown at hanlp/utils/span_util.py:591

    span of the same type.

    In the BIO scheme, I is a token inside a span, O is a token outside
    a span and B is the beginning of a span.

    # Parameters

    tag_sequence : `List[str]`, required.
        The tag sequence encoded in IOB1, e.g. ["I-PER", "I-PER", "O"].
    encoding : `str`, optional, (default = `"IOB1"`).
        The encoding type to convert from. Must be either "IOB1" or "BIO".

    # Returns

    bioul_sequence : `List[str]`
        The tag sequence encoded in IOB1, e.g. ["B-PER", "L-PER", "O"].
    """
    if encoding not in {"IOB1", "BIO"}:
        raise ValueError(f"Invalid encoding {encoding} passed to 'to_bioul'.")

    def replace_label(full_label, new_label):
        # example: full_label = 'I-PER', new_label = 'U', returns 'U-PER'
        parts = list(full_label.partition("-"))
        parts[0] = new_label
        return "".join(parts)

    def pop_replace_append(in_stack, out_stack, new_label):
        # pop the last element from in_stack, replace the label, append
        # to out_stack
        tag = in_stack.pop()
        new_tag = replace_label(tag, new_label)
        out_stack.append(new_tag)

    def process_stack(stack, out_stack):
        # process a stack of labels, add them to out_stack
        if len(stack) == 1:
            # just a U token

View on GitHub (pinned to ddb1299bdd)

Solutions

  1. Pass exactly 'IOB1' or 'BIO' (uppercase)
  2. If your scheme is IOB2/BIO2, use encoding='BIO'
  3. If your source is IOBES/BIOUL, you don't need this converter — decode with iobes_tags_to_spans/bioul_tags_to_spans directly

Example fix

# before
bioul = to_bioul(tags, encoding='IOB2')  # ValueError
# after
bioul = to_bioul(tags, encoding='BIO')
Defensive patterns

Strategy: validation

Validate before calling

assert encoding in {'IOB1', 'BIO'}, f"encoding must be IOB1 or BIO, got {encoding}"

Type guard

def is_supported_encoding(enc: str) -> bool:
    return enc in ('IOB1', 'BIO')

Try / catch

try:
    to_bioul(tags, encoding=enc)
except ValueError:
    to_bioul(tags, encoding='BIO')  # IOB2 == BIO

Prevention

When it happens

Trigger: Calling to_bioul(tag_sequence, encoding=...) with encoding not in {'IOB1','BIO'} — commonly via iob1_to_bioul wrappers or direct calls with 'IOB2' (which is the same as BIO but spelled differently) or lowercase 'iob1'.

Common situations: Copy-pasted scheme names from other libraries (IOB2, BIOES, IOBES); case-sensitive string mismatch; assuming any standard scheme name is accepted.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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