Skip to content

fix(opencode): filter empty text/reasoning parts when loading from database#19311

Open
erichasinternet wants to merge 1 commit intoanomalyco:devfrom
erichasinternet:fix/filter-empty-parts-on-load
Open

fix(opencode): filter empty text/reasoning parts when loading from database#19311
erichasinternet wants to merge 1 commit intoanomalyco:devfrom
erichasinternet:fix/filter-empty-parts-on-load

Conversation

@erichasinternet
Copy link
Copy Markdown

@erichasinternet erichasinternet commented Mar 26, 2026

Issue for this PR

Closes #19309

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds defensive filtering when loading parts from the database to handle corrupted sessions with empty text/reasoning blocks. This complements PR #17742's prevention approach.

Problem
Users with already-corrupted databases (empty text blocks stored in part table) experience permanent ValidationException errors with AWS Bedrock, especially when using LiteLLM proxy (@ai-sdk/openai-compatible). PR #17742 prevents future corruption but doesn't fix existing corrupted data.

Solution
Filter empty text/reasoning parts at two levels:

  1. Database load time (message-v2.ts line ~562): When hydrating parts from database, skip parts with empty/whitespace-only text
  2. Conversion time (message-v2.ts lines ~651, ~707, ~770): When converting to model messages, skip text/reasoning parts with empty/whitespace text

Both use .trim() to catch whitespace-only content.

Why this approach?

  • Minimal change - Only adds filtering checks, no storage logic changes
  • Defensive - Protects against any empty parts (past, present, future)
  • Automatic recovery - Fixes corrupted sessions without manual scripts
  • Complements fix(opencode): filter empty text content blocks for all providers #17742 - That PR prevents creation, this handles recovery
  • Low risk - Only affects loading/conversion, doesn't change storage

Relationship to PR #17742
Both PRs should be merged for complete coverage:

How did you verify your code works?

  1. New tests added (5 test cases in message-v2.test.ts):

    • Filters empty text parts
    • Filters whitespace-only text parts
    • Filters empty reasoning parts
    • Preserves non-text parts (tool calls) when text is empty
    • Tests both user and assistant messages
  2. All existing tests pass: 26 tests, 41 expect() calls, 0 failures

  3. Typecheck passes: bun run typecheck completes with no errors

  4. Real-world validation: Tested with database containing 26 empty parts - sessions load successfully without ValidationException

Screenshots / recordings

N/A - Backend logic change, no UI impact

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions bot added the needs:compliance This means the issue will auto-close after 2 hours. label Mar 26, 2026
@github-actions
Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

The search results show that PR #19311 (the current PR) is related to PR #17742, but they are not duplicates — they are complementary:

According to the PR description, both should be merged as they provide complete coverage: prevention + recovery.

No duplicate PRs found

@github-actions github-actions bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Mar 26, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

…tabase

Empty text and reasoning parts with blank or whitespace-only text can
be stored in the database during streaming (from text-start events that
receive no deltas, or when streams are interrupted). These empty parts
cause permanent ValidationException errors with providers like AWS
Bedrock, especially when using LiteLLM proxy (@ai-sdk/openai-compatible).

This fix adds defensive filtering at two levels:
1. When hydrating parts from database (filters on load)
2. When converting to model messages (filters during conversion)

Both filters use .trim() to catch whitespace-only content.

Fixes anomalyco#19309
Complements anomalyco#17742 (prevention) with recovery for existing corruption
@erichasinternet erichasinternet force-pushed the fix/filter-empty-parts-on-load branch from a8eaa85 to 203e02f Compare March 26, 2026 15:43
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.

Empty content blocks persist in database causing permanent Bedrock ValidationException (LiteLLM/openai-compatible proxies)

1 participant