Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AI_InvalidPromptError: Invalid prompt: messages must be an array of CoreMessage or UIMessage #5499

Closed
HomyeeKing opened this issue Apr 2, 2025 · 11 comments
Assignees
Labels
ai/core bug Something isn't working

Comments

@HomyeeKing
Copy link

HomyeeKing commented Apr 2, 2025

Description

After upgrade the ai-sdks to the latest, the exact version are list below, can't get pass the zod validation.

  1. setMessages modify the original message object and fill the part property https://github.com/vercel/ai/blob/main/packages/react/src/use-chat.ts#L465
  2. I thought the new part property failed the zod validation, so I use convertToCoreMessages this util to remove it, unfortunately still can't pass the validation
  3. the part of the user message was removed, but the assistant message is formatted to mismatch the CoreAssistantMessage

Code example

import { convertToCoreMessages } from 'ai';

const res = convertToCoreMessages([
  {
    role: 'assistant',
    content: [
      {
        type: 'text',
        text: 'xxxxxxxxx',
      },
    ],
    parts: [
      {
        type: 'text',
        text: [
          {
            type: 'text',
            text: 'xxxxxxxxxxx',
          },
        ],
      },
    ],
  },
]);

console.log('res', res);

AI provider

"@ai-sdk/provider": "^1.1.0",

Additional context

"@ai-sdk/openai": "^1.3.6",
  "@ai-sdk/openai-compatible": "^0.2.4",
  "@ai-sdk/provider": "^1.1.0",
  "@ai-sdk/provider-utils": "^2.2.3",
  "@ai-sdk/react": "^1.2.5",
  "ai": "^4.2.10"
@HomyeeKing HomyeeKing added the bug Something isn't working label Apr 2, 2025
@HomyeeKing HomyeeKing reopened this Apr 2, 2025
@HomyeeKing
Copy link
Author

so should fix the type definition of CoreAssistantMessage or the convertToCoreMessages logic

@iteratetograceness
Copy link
Collaborator

@HomyeeKing could you help me understand where you're getting the assistant message you're passing to convertToCoreMessages?

in the code snippet you shared there are some type discrepancies:

{
    role: 'assistant',
    content: [ // expected type is string
      {
        type: 'text',
        text: 'xxxxxxxxx',
      },
    ],
    parts: [
      {
        type: 'text',
        text: [ // expected type is string
          {
            type: 'text',
            text: 'xxxxxxxxxxx',
          },
        ],
      },
    ],
  }

@HomyeeKing
Copy link
Author

HomyeeKing commented Apr 6, 2025

@iteratetograceness
the assistant messages are from generateText

const { messages, setMessages } = useChat({
 // ....
})
const { response } = await generateText({
  model: openai('gpt-4o'),
  messages: messages
});
// setMessages fills every type of message with `part` property 
// so it will mismatch the
// Array<CoreSystemMessage | CoreUserMessage | CoreAssistantMessage | CoreToolMessage> | Array<UIMessage>
setMessages(...response.messages)

then I use convertToCoreMessages to make the messages valid

// ...
const { response } = await generateText({
  // ...
  messages: convertToCoreMessages(messages)
});

// ....

then the assistant messages are mismatched CoreAssistantMessage again

@longfin
Copy link

longfin commented Apr 8, 2025

In my case, this part seems to produce an illegal core message payload.

before

 {
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": "<text>\n\n"
    }
  ],
  "id": "<id>",
  "createdAt": "2025-04-08T10:44:44.367Z",
  "parts": [
    {
      "type": "text",
      "text": [
        {
          "type": "text",
          "text": "<text>\n\n"
        }
      ]
    }
  ]
}

after

  {
    "role": "user",
    "content": [
      {
        "type": "text",
        "text": [
          {
            "type": "text",
            "text": "<text>\n\n"
          }
        ]
      }
    ]
  },

@iteratetograceness
Copy link
Collaborator

@HomyeeKing ah, so a couple of issues here!

First, you're attempting to pass the CoreMessage array returned from generateText to the useChat hook's setMessages, which expects UI Messages. You'll have to convert CoreMessage to UIMessage before passing to setMessages.

Secondly, what's your use case for using generateText with useChat? The hook is meant to interact with an API route that returns a data stream response (see here).

@iteratetograceness
Copy link
Collaborator

@longfin your before payload itself appears to be invalid, it's a mesh of both UIMessage and CoreMessage. Can you help me understand where your before payload is coming from?

@HomyeeKing
Copy link
Author

HomyeeKing commented Apr 9, 2025

@iteratetograceness

  1. Yes, you got the picture.
  2. I thought it will simplify the process of implementing the Chat UI before I recognized it should work with the tools defined in server. So far I just define the frontend tool and just use the messages and setMessages to manage the message state. I DO NOT fully make use of the useChat

@iteratetograceness
Copy link
Collaborator

@HomyeeKing I recommend using the boilerplate code—it's quite quick to get things set up even while you're building out chat UI! You could even hook it up, copy the initial array of messages returned and use as mock data.

But if you prefer to stick to your approach your issue should be resolved as long as you convert the messages returned from generateText to the UIMessage type.

Will close this issue unless @longfin has a similar but different concern!

@longfin
Copy link

longfin commented Apr 9, 2025

@longfin your before payload itself appears to be invalid, it's a mesh of both UIMessage and CoreMessage. Can you help me understand where your before payload is coming from?

My payload was created by useChat() hook like this.

Will close this issue unless @longfin has a similar but different concern!

Agree, I'll open a new issue having more detailed context soon.

@HomyeeKing
Copy link
Author

HomyeeKing commented Apr 10, 2025

@iteratetograceness but I still have one question:
why not let useChat work with client-side tools like generateText, i.e.

const [] = useChat({
   model: xxx,
	tools: xxx
})

I think it's one common way(I don't have specific statistics) for developers to use it that way and the current one needs to define tools on server-side which might spends extra time to implement, not firendly to make a quick app

@iteratetograceness
Copy link
Collaborator

@HomyeeKing client-side tools are supported with useChat! See this docs page: https://sdk.vercel.ai/docs/ai-sdk-ui/chatbot-tool-usage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ai/core bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants