linshenkx/prompt-optimizer · error · RequestConfigError
Messages array cannot be empty
Error message
Messages array cannot be empty
What it means
Thrown by validateMessages in the abstract LLM adapter when the messages array passed to sendMessage / sendMessageStream / sendMessageStreamWithTools has zero elements. The adapter refuses to build a provider request with no conversation content because every chat API requires at least one message. It is a client-side RequestConfigError raised before any network call.
Source
Thrown at packages/core/src/services/llm/adapters/abstract-adapter.ts:184
): Promise<void> {
this.validateImageUnderstandingRequest(request)
await this.doSendImageUnderstandingStream(request, config, callbacks)
}
// ===== 公共验证方法 =====
/**
* 验证消息数组格式
* @param messages 消息数组
* @throws {RequestConfigError} 当消息数组无效时
*/
protected validateMessages(messages: Message[]): void {
if (!Array.isArray(messages)) {
throw new RequestConfigError('Messages must be an array')
}
if (messages.length === 0) {
throw new RequestConfigError('Messages array cannot be empty')
}
for (const msg of messages) {
if (!msg.role || !msg.content) {
throw new RequestConfigError('Each message must have role and content')
}
if (!['system', 'user', 'assistant', 'tool'].includes(msg.role)) {
throw new RequestConfigError(`Invalid message role: ${msg.role}`)
}
if (typeof msg.content !== 'string') {
throw new RequestConfigError('Message content must be a string')
}
}
}
protected validateImageUnderstandingRequest(request: ImageUnderstandingRequest): void {View on GitHub (pinned to 3e677b1d9f)
Solutions
- Ensure at least one message is included, typically the user's prompt: messages = [{role:'user', content: prompt}]
- If messages are built from history, append/prepend the current user turn after mapping history
- Add a guard before calling send* to short-circuit when messages.length === 0
Example fix
// before
await adapter.sendMessage([], { model: 'gpt-4' })
// after
await adapter.sendMessage([{ role: 'user', content: 'Hello' }], { model: 'gpt-4' }) Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(messages) || messages.length === 0) {
throw new Error('Refusing to call LLM with no messages')
}
await adapter.sendMessage(messages, opts) Type guard
null
Try / catch
null
Prevention
- Always append the current user turn before sending
- Guard messages.length > 0 before calling send* APIs
When it happens
Trigger: Calling sendMessage([], ...), sendMessageStream([]), or sendMessageStreamWithTools([]) with an empty array; building messages dynamically (e.g. mapping an empty history and forgetting a user prompt) and passing the result.
Common situations: Chat-history-driven apps where the history array is empty on first turn and the code forgets to prepend the user's message; filtering out all messages (e.g. by role) before sending; passing an uninitialized [] variable.
Related errors
- Each message must have role and content
- Invalid message role: ${msg.role}
- Message content must be a string
- DATA_ERROR_CODES.ELECTRON_API_UNAVAILABLE
- Image understanding request requires at least one image
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/393102b8c8cafcfa.
Report an issue: GitHub.