Skip to content

Python: Bug: split_plaintext_paragraph / split_markdown_paragraph can return a chunk larger than max_tokens #14566

Closed as not planned

Description

Describe the bug

split_plaintext_paragraph and split_markdown_paragraph can return a paragraph whose token count is above max_tokens.

At the end of _split_text_paragraph, a short last paragraph is merged into the previous one. The merge check counts words (len(paragraph.split(" "))) instead of calling token_counter:

if token_counter(last_para) < max_tokens / 4:
last_para_tokens = last_para.split(" ")
sec_last_para_tokens = sec_last_para.split(" ")
last_para_token_count = len(last_para_tokens)
sec_last_para_token_count = len(sec_last_para_tokens)
if last_para_token_count + sec_last_para_token_count <= max_tokens:
sec_last_para = " ".join(sec_last_para_tokens) + NEWLINE
last_para = " ".join(last_para_tokens)
new_sec_last_para = sec_last_para + last_para
paragraphs[-2] = new_sec_last_para.strip()
paragraphs.pop()

A word is usually more than one token, so the merged paragraph can go over the limit even though the word count is under it. This matters when max_tokens is the embedding model's input limit.

To Reproduce

With the default token counter, using the input of the existing test_split_text_paragraph_evenly test:

from semantic_kernel.text import split_plaintext_paragraph

text = [
    "This is a test of the emergency broadcast system. This is only a test.",
    "We repeat, this is only a test. A unit test.",
    "A small note. And another. And once again. Seriously, this is the end. We're finished. All set. Bye.",
    "Done.",
]
chunks = split_plaintext_paragraph(text, 15)
print([len(c) // 4 for c in chunks])  # [12, 5, 11, 10, 16] -> last chunk is 16 tokens, limit is 15

With a real tokenizer (tiktoken, cl100k_base) passed as token_counter, on generated multi-line English text and limits from 64 to 512, 955 of 8000 runs (about 12%) returned an over-limit chunk. The worst one was 314 tokens for max_tokens=256.

Expected behavior

No returned paragraph is above max_tokens. The last paragraph should only be merged into the previous one if the merged text fits, measured with token_counter.

Platform

  • Language: Python
  • Source: main at cc8a15f
  • OS: Windows 11, Python 3.12

Additional context

Eight existing unit tests in tests/unit/text/test_text_chunker.py expect an over-limit last chunk (for example 16 tokens with max_token_per_line = 15). A fix would change their expected output, so I wanted to raise it here first. I have a small fix with tests ready and I'm happy to open the PR.

Activity

  1. xThreeh commented on Oct 8, 2026

    @xThreeh
    Author

    Closing as a duplicate: open PR #14238 already fixes this.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    pythonPull requests for the Python Semantic Kerneltriage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions