vercel/ai · error · InvalidPromptError

Moonshot AI Partial Mode requires the partial assistant mess

Error message

Moonshot AI Partial Mode requires the partial assistant message to be the final message.

What it means

Moonshot AI 'Partial Mode' (moonshotMessageOptions.partial = true) lets you send an incomplete assistant message as a prefix for the model to continue. The Moonshot API only accepts such a partial assistant message as the LAST message of the prompt, so the converter throws InvalidPromptError if it appears earlier.

Source

Thrown at packages/moonshotai/src/convert-to-moonshotai-chat-messages.ts:295

                      functionality: `file part media type ${part.mediaType}`,
                    });
                  }
                }
              }
            }
          }),
          ...(moonshotMessageOptions?.name != null && {
            name: moonshotMessageOptions.name,
          }),
        });

        break;
      }

      case 'assistant': {
        if (moonshotMessageOptions?.partial === true) {
          if (index !== prompt.length - 1) {
            throw new InvalidPromptError({
              prompt,
              message:
                'Moonshot AI Partial Mode requires the partial assistant message to be the final message.',
            });
          }

          if (responseFormat?.type === 'json_object') {
            throw new InvalidPromptError({
              prompt,
              message:
                'Moonshot AI Partial Mode cannot be combined with JSON object response format.',
            });
          }
        }

        let text = '';
        let reasoning = '';
        const toolCalls: Array<{

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Ensure the partial assistant message is the last element of the prompt array.
  2. Remove additional messages that come after the partial assistant message.
  3. Set partial: false (or omit it) if you need the message in the middle of the conversation.
  4. Reorder so only the prefix assistant message is partial and nothing follows it.

Example fix

// before
messages: [user('hi'), assistant('partial...', { partial: true }), user('more')]
// after
messages: [user('hi'), assistant('partial...', { partial: true })]
Defensive patterns

Strategy: validation

Validate before calling

const last = messages[messages.length - 1];
if (last?.role === 'assistant' && (last.providerOptions?.moonshot as any)?.partial === true && messages.length > 1) {
  // OK only if it IS the final message; error if any earlier message has partial
}
const badIndex = messages.slice(0, -1).findIndex(m => m.role === 'assistant' && (m.providerOptions?.moonshot as any)?.partial === true);
if (badIndex !== -1) throw new Error(`partial assistant message must be last (index ${badIndex})`);

Type guard

function isFinalPartialAssistant(messages: ModelMessage[]): boolean {
  const last = messages.at(-1);
  return !!last && last.role === 'assistant' &&
    !messages.slice(0, -1).some(m => m.role === 'assistant' && (m.providerOptions?.moonshot as any)?.partial === true);
}

Try / catch

import { InvalidPromptError } from '@ai-sdk/provider';
try {
  await generateText({ model: moonshot(modelId), messages });
} catch (e) {
  if (InvalidPromptError.isInstance(e) && e.message.includes('Partial Mode')) {
    // sanitize messages: drop trailing turns or unset partial
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing providerOptions.moonshot.partial = true on an assistant message that is not the final message in the messages array (e.g. followed by more assistant/user turns).

Common situations: Building a continue-generation feature but appending the partial assistant message before tool results or additional turns; iterating over histories and blindly marking the last assistant message found rather than the actual final message.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/4f10631c98ff8d25. Report an issue: GitHub.