fix(history): tolerate non-array message content in blocksToText - #262
Open
dex0shubham wants to merge 1 commit into
Open
fix(history): tolerate non-array message content in blocksToText#262dex0shubham wants to merge 1 commit into
dex0shubham wants to merge 1 commit into
Conversation
blocksToText handled the string case then fell into `for (const blk of content)`,
assuming an array. An untrusted body carrying `content: null` (or any non-array)
makes the for...of throw `TypeError: content is not iterable`. The collapse path
reaches it with raw, unvalidated content (messagesToHistorySegments -> blocksToText
on assistant turns, and via withoutTypedUserText which returns null unchanged for
user turns), so a single `{"role":"assistant","content":null}` turn 502s the whole
request ("pxpipe transform failed").
Every sibling serializer/scanner in this module already guards this
(findClosedPrefixBoundary, withoutTypedUserText, splitUserTyped, messageCacheControl
all `if (!Array.isArray(...))`). Add the same guard so a malformed turn serializes
to empty and passes through.
dex0shubham
force-pushed
the
fix/blockstotext-nonarray
branch
from
September 2, 2026 07:14
4078861 to
1a91500
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
blocksToText(src/core/history.ts) handles thestringcase, then does:assuming an array. An untrusted request body can carry a non-array
content(e.g.{"role":"assistant","content":null}), andfor...of nullthrowsTypeError: content is not iterable.The collapse path reaches this with raw, unvalidated content:
messagesToHistorySegmentscallsblocksToText(m.content)for assistant turns (and viawithoutTypedUserText, which returnsnullunchanged, for user turns), andreq.messagesis only checked with an outerArray.isArray— individualcontentfields are never validated. The throw propagates out oftransformRequestand is turned into a 502 "pxpipe transform failed" at the proxy, so one malformed turn fails the whole request.Every sibling in the module already guards exactly this shape and passes it through:
findClosedPrefixBoundary,withoutTypedUserText,splitUserTyped,messageCacheControl(and the OpenAI-path twinchatContentToText).blocksToTextwas the lone exception.Fix
Add the same
!Array.isArray(content)guard, returning''— a malformed turn serializes to empty and passes through instead of 502ing.Added a unit test (
blocksToText(null)/undefined), verified it throws on the old code and passes with the fix.Full suite green (1207/1207);
typecheckclean.