Skip to content

Conversation

@shoaibansari5398
Copy link

What does this PR do?

Fixes #8862 - Resolves "Invalid prompt at compaction" error (AI_InvalidPromptError) during session compaction.

Problem: The error "The messages must be a ModelMessage[]" occurred when convertToModelMessages failed validation. This happened because
toModelMessage
was occasionally passing:

Empty messages (with 0 parts) to the converter.
undefined values for attachments or providerMetadata in tool-result parts, which some AI providers (like Anthropic) check strictly.

How did you verify your code works?

Solution:

Filter empty messages: Added a filter to remove messages with parts.length === 0 before conversion.
Safeguard Tool Results:
Default attachments to [] if undefined.
Default callProviderMetadata to {} if undefined.
typescript
const filtered = result
.filter((msg) => msg.parts.length > 0) // Filter out empty messages
.filter((msg) => msg.parts.some((part) => part.type !== "step-start"))
return convertToModelMessages(filtered, {
tools: options?.tools,
})

How did you verify your code works?
Verified by code inspection that filtered array will strictly contain messages with content, satisfying
ModelMessage
requirements.
Verified that part.state.attachments and part.metadata access is now null-safe, preventing undefined values from reaching the AI SDK validators.

@github-actions
Copy link
Contributor

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

No duplicate PRs found

)
const filtered = result
.filter((msg) => msg.parts.length > 0)
.filter((msg) => msg.parts.some((part) => part.type !== "step-start"))
Copy link
Contributor

@jerome-benoit jerome-benoit Jan 16, 2026

Choose a reason for hiding this comment

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

The filter can do both at the same time. And I still think the empty string checks in all the codebase should handle spaces properly: #7086

const filtered = result.filter((msg) => 
  msg.parts.length > 0 && 
  msg.parts.some((part) => part.type !== "step-start")
)

Copy link
Contributor

@jerome-benoit jerome-benoit left a comment

Choose a reason for hiding this comment

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

Adding unit tests would avoid such regression to happen again.

@Dreaming-Codes
Copy link

Can confirm that I've encountered the same problem and this fixed it

@shoaibansari5398
Copy link
Author

@jerome-benoit Thank you for the review!

I've updated the PR with the following changes:

Optimization: Combined the .filter() calls as requested.
Tests: Added a regression test (issue-8862.test.ts) to verify that undefined metadata/attachments are handled correctly without crashing.
Conflict Resolution: Rebased and resolved conflicts with origin/dev, adapting to the new attachment handling logic while preserving the null-safety fix.
@Dreaming-Codes Thanks for confirming the fix works for you!

Ready for re-review.

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.

Bug: Invalid prompt at compaction

3 participants