Skip to content

🩹 fix: Drop Null/Empty Reasoning Blocks in the v1 Bedrock Converter - #309

Merged
danny-avila merged 6 commits into
LibreChat-AI:mainfrom
jomspk:fix/bedrock-v1-reasoning-null-text
Jul 14, 2026
Merged

danny-avila merged 6 commits into
LibreChat-AI:mainfrom
jomspk:fix/bedrock-v1-reasoning-null-text

Conversation

@jomspk

@jomspk jomspk commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Problem

#248 guarded the native-Bedrock converter (convertAIMessageToConverseMessage) against reasoning blocks whose reasoningText.text is null/empty, but the v1 converter (convertFromV1ToChatBedrockConverseMessage, taken when response_metadata.output_version === 'v1') still serializes reasoning unguarded in both of its branches:

} else if (block.type === 'reasoning') {
  const reasoning = block as { reasoning: string };
  assistantMsg.content?.push({
    reasoningContent: { reasoningText: { text: reasoning.reasoning } }, // ← no null/empty check
  } as BedrockContentBlock);
} else if (block.type === 'reasoning_content') {
  assistantMsg.content?.push({
    reasoningContent: langchainReasoningBlockToBedrockReasoningBlock(block), // ← no isSerializableBedrockReasoningBlock guard
  } as BedrockContentBlock);
}

A v1 reasoning block whose reasoning is null/empty — e.g. produced by a model that omits reasoning text by default (thinking.display: "omitted", the default on Claude Opus 4.7+ / Sonnet 5) — reaches Bedrock as reasoningText: { text: null } and the whole request is rejected:

1 validation error detected: Value at 'messages.N.member.content.M.member.reasoningContent.reasoningText.text'
failed to satisfy constraint: Member must not be null

We hit exactly this in a LibreChat deployment: Bedrock anthropic.claude-sonnet-5 + MCP tools fails on the tool-call replay turn with the error above. It is the same failure class #248 fixed — #248's "Scope / remaining gap" section covers the non-streaming @langchain/aws delegation but not this v1 path in the same file, which is still unguarded on main / 3.2.63.

Fix

Apply #248's drop-the-unsendable-block approach to the v1 converter:

  • reasoning (v1 standard block): drop when reasoning is null/empty.
  • reasoning_content: gate on the existing isSerializableBedrockReasoningBlock before converting, same as the non-v1 path.
  • Add the BEDROCK_EMPTY_TEXT_PLACEHOLDER fallback (from 🩹 fix: Drop Foreign Reasoning Blocks in Anthropic Message Converter #243) when the drop leaves a turn with no content blocks and no tool calls — mirroring the non-v1 converter, so the drop can't trade the null-text 400 for an empty-content 400.

Blocks carrying real text (or redacted content) are converted unchanged.

Change Type

  • Bug fix (non-breaking change which fixes an issue)

Testing

Test-first: added a convertToConverseMessages — v1 reasoning serialization describe block to message_inputs.test.ts (5 cases; 4 fail without the fix, reproducing reasoningText: { text: undefined } passing through):

  • v1 reasoning block with missing reasoning → dropped; sibling text + tool calls survive
  • v1 reasoning block with empty reasoning → dropped
  • v1 signature-only reasoning_content block → dropped
  • v1 turn emptied by the drop → placeholder emitted, not empty content
  • v1 reasoning / reasoning_content blocks carrying real text → still converted (not over-dropped)

Test Configuration:

  • npx jest src/llm/bedrock: 9 suites / 106 passed, 4 skipped, 0 failed
  • Wider npx jest src/llm src/messages: only failures are 4 pre-existing env-dependent suites (invoke, google, anthropic, vertexai) that fail identically on a clean main checkout without this change
  • npx tsc --noEmit, npx eslint, npx prettier --check on changed files: clean
  • Verification is unit-level; no live Bedrock run was performed for this PR (the production error above is from a real deployment, and the raw-Converse repro in 🩹 fix: Drop Bedrock Reasoning Blocks With Null/Empty Text #248 already demonstrates Bedrock's rejection of null-text reasoning blocks)

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • I have commented in any complex areas of my code
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes

🤖 Generated with Claude Code

jomspk and others added 2 commits July 14, 2026 10:45
Apply the LibreChat-AI#248 null/empty-text guard to
convertFromV1ToChatBedrockConverseMessage: drop `reasoning` blocks whose
`reasoning` is null/empty and `reasoning_content` blocks that fail
isSerializableBedrockReasoningBlock, and fall back to the empty-turn
placeholder when the drop empties the turn — instead of sending
`reasoningText: { text: null }`, which Bedrock Converse rejects with
`Member must not be null`.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 541bbe3822

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/llm/bedrock/utils/message_inputs.ts
Comment thread src/llm/bedrock/utils/message_inputs.ts Outdated

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d0c84a0939

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/llm/bedrock/utils/message_inputs.ts Outdated

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b7ca42e95

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/llm/bedrock/utils/message_inputs.ts

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c390f0240a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/llm/bedrock/utils/message_inputs.ts Outdated

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 3c00ae3f8b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danny-avila
danny-avila merged commit 319a03a into LibreChat-AI:main Jul 14, 2026
13 checks passed
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