Skip to content

fix: TiktokenCounter counts literal special-token strings as ordinary text - #12888

Closed
Shubhampm18 wants to merge 1 commit into
deepset-ai:mainfrom
Shubhampm18:fix/tiktoken-counter-literal-special-tokens
Closed

Shubhampm18 wants to merge 1 commit into
deepset-ai:mainfrom
Shubhampm18:fix/tiktoken-counter-literal-special-tokens

Conversation

@Shubhampm18

Copy link
Copy Markdown

Related Issues

Proposed Changes

TiktokenCounter.count() rendered messages/tools through Encoding.encode(), whose disallowed_special="all" default raises ValueError on text that merely contains a special-token marker such as <|endoftext|>. Since allowed_special defaults to an empty set, encode() can never emit a special token here — the strict check only turns ordinary source text into a crash.

Switches to encode_ordinary(), mirroring the fix already merged for the token-based document splitters (#12853), and notes the behavior in the constructor docstring.

How did you test it?

  • Reproduced the original crash against real tiktoken first (encode() raises; encode_ordinary() counts fine).
  • test/token_counters/test_tiktoken_counter.py: 15 passed. The fake encoder now records encode_ordinary and fails loudly if encode() is used again; new unit + parameterized real-encoder integration tests cover the literal marker.
  • ruff check and ruff format --check pass on the changed files.
  • Added a reno release note.

Notes for the reviewer

The change is one call-site in count(); everything else is tests/docs. This was the last remaining bare .encode() of user-supplied text in haystack/ after #12853, as noted in the issue.

This PR was fully generated with an AI assistant. I have reviewed the changes and run the relevant tests.

… text

count() encoded rendered messages/tools via Encoding.encode(), whose
disallowed_special="all" default raises ValueError on text that merely
contains a special-token marker such as the endoftext sentinel. Since
allowed_special defaults to an empty set, encode() can never emit a
special token here -- the strict check only turns ordinary source text
into a crash.

Switch to encode_ordinary(), mirroring the fix already landed for the
token-based document splitters (deepset-ai#12853), and note the behavior in the
constructor docstring. The fake encoder in the tests records calls to
encode_ordinary and fails loudly if encode() is used again.

Fixes deepset-ai#12869
Copilot AI lite review requested due to automatic review settings September 23, 2026 15:22
@Shubhampm18
Shubhampm18 requested a review from a team as a code owner September 23, 2026 15:22
@Shubhampm18
Shubhampm18 requested review from julian-risch and removed request for a team September 23, 2026 15:22
@vercel

vercel Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

@Shubhampm18 is attempting to deploy a commit to the deepset Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

CLAassistant commented Sep 23, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions

Copy link
Copy Markdown
Contributor

Hi @Shubhampm18, thanks for your interest in contributing to Haystack! 🙏

⚠️ Issue #12869 is already being addressed by open pull request(s) #12871, #12876, #12879. Before opening a PR for an issue, please check whether a PR is already linked to it, and consider contributing to the existing PR instead. We may close duplicate PRs to keep the review queue manageable.

This is an automated message to help us keep the review queue healthy.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Add tool-schema regression coverage and document the behavior in the relevant documentation pages.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
What changed in this PR

This PR fixes TiktokenCounter crashes on literal tiktoken special-token strings.

Changes:

  • Uses encode_ordinary() for rendered messages and tools.
  • Adds regression tests and documentation.
  • Adds a release note.
File Description
test/​token_counters/​test_tiktoken_counter.py Adds special-token regression coverage.
releasenotes/​notes/​fix-tiktoken-counter-special-tokens-3a8f27d1e6b4c05a.yaml Documents the bug fix.
haystack/​token_counters/​tiktoken_counter.py Uses ordinary encoding for rendered content.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +103 to +105
def test_counts_literal_special_token_text_as_ordinary(self, fake_encoder):
# Regression for #12869: count() must route text through encode_ordinary so a literal
# special-token marker cannot raise the way encode()'s disallowed_special="all" default would.
@julian-risch

Copy link
Copy Markdown
Member

Thank you for your efforts! We're closing this PR because it duplicates #13009, which makes the same one-line fix to TiktokenCounter.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TiktokenCounter raises ValueError on literal special-token strings like <|endoftext|>

4 participants