Skip to content

Fix token_to_sequence returning Some(0) for out-of-bounds index#2214

Open
Osamaali313 wants to merge 1 commit into
huggingface:mainfrom
Osamaali313:fix/token-to-sequence-out-of-bounds
Open

Fix token_to_sequence returning Some(0) for out-of-bounds index#2214
Osamaali313 wants to merge 1 commit into
huggingface:mainfrom
Osamaali313:fix/token-to-sequence-out-of-bounds

Conversation

@Osamaali313

Copy link
Copy Markdown

Problem

Encoding::token_to_sequence guards the index with > instead of >=:

pub fn token_to_sequence(&self, token: usize) -> Option<usize> {
    if token > self.len() {
        None
    } else if self.sequence_ranges.is_empty() {
        Some(0)
    } else {
        self.sequence_ranges.iter().find_map(|(seq_id, range)| {
            if range.contains(&token) { Some(*seq_id) } else { None }
        })
    }
}

Valid token indices are 0..len, so token == len is out of bounds and should return None. But token > self.len() lets it through, and for an unprocessed encoding (empty sequence_ranges, e.g. from Encoding::from_tokens or a raw model output) it falls to Some(0).

Evidence (sibling accessors prove intent)

Every other index-based accessor in the same file treats index >= len as out of bounds:

  • token_to_charsself.offsets.get(token)None at token == len
  • token_to_wordself.words.get(token)None at token == len

Only token_to_sequence admits token == len. token_to_sequence is public API (also exposed through the Python and Node bindings), so a caller doing encoding.token_to_sequence(len) on a single-sequence/unprocessed encoding gets 0 rather than None.

Fix

if token >= self.len() {

Processed encodings are unaffected — their sequence_ranges are populated and never contain len, so the boundary already resolved to None via find_map; existing tests (processors::bert, processors::roberta, Python test_encoding.py) still pass. A regression test is added for the unprocessed-encoding boundary.

`Encoding::token_to_sequence` guarded with `if token > self.len()`, so the
index `token == len` (one past the last valid token) fell through. For an
unprocessed encoding (empty `sequence_ranges`) it then returned `Some(0)`
instead of `None`.

Valid token indices are `0..len`, and the sibling accessors treat
`index >= len` as out of bounds: `token_to_chars` uses
`self.offsets.get(token)` and `token_to_word` uses `self.words.get(token)`,
both of which yield `None` at `token == len`. Use `>=` so
`token_to_sequence` agrees with them.

Processed encodings are unaffected (their populated `sequence_ranges` never
contain `len`), so existing tests still pass. Adds a regression test for the
unprocessed-encoding boundary.
Copilot AI review requested due to automatic review settings July 17, 2026 19:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants