{"record":{"id":"884f6b3c691f88e4","repo":"vercel/ai","slug":"deepseek-assistant-prefix-completion-requires-pre","errorCode":null,"errorMessage":"DeepSeek assistant prefix completion requires `prefix: true` on an assistant message.","messagePattern":"DeepSeek assistant prefix completion requires `prefix: true` on an assistant message\\.","errorType":"validation","errorClass":"InvalidPromptError","httpStatus":null,"severity":"error","filePath":"packages/deepseek/src/chat/convert-to-deepseek-chat-messages.ts","lineNumber":96,"sourceCode":"      lastUserMessageIndex = i;\n      break;\n    }\n  }\n\n  let index = -1;\n  for (const { role, content, providerOptions } of prompt) {\n    index++;\n\n    // The assistant schema extends the common message schema, so one parse\n    // validates names for every role and the assistant-only prefix option.\n    const deepseekMessageOptions = await parseProviderOptions({\n      provider: providerOptionsName,\n      providerOptions,\n      schema: deepseekAssistantMessageProviderOptions,\n    });\n\n    if (deepseekMessageOptions?.prefix === true && role !== 'assistant') {\n      throw new InvalidPromptError({\n        prompt,\n        message:\n          'DeepSeek assistant prefix completion requires `prefix: true` on an assistant message.',\n      });\n    }\n\n    switch (role) {\n      case 'system': {\n        messages.push({\n          role: 'system',\n          content,\n          ...(deepseekMessageOptions?.name != null && {\n            name: deepseekMessageOptions.name,\n          }),\n        });\n        break;\n      }\n","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/deepseek/src/chat/convert-to-deepseek-chat-messages.ts#L78-L114","documentation":"DeepSeek's assistant-prefix (FIM-style) completion is only valid on assistant messages. The SDK throws InvalidPromptError when provider options set prefix: true on a message whose role is not 'assistant' (the check reads deepseekMessageOptions?.prefix === true && role !== 'assistant').","triggerScenarios":"Passing prefix: true via deepseek provider options on a user, system, or tool message, e.g. experimental_providerOptions: { deepseek: { prefix: true } } on a non-assistant message in a prompt array.","commonSituations":"Porting OpenAI-style prefix code where the flag was applied generically to all messages; generating options in a loop without checking role; misunderstanding that prefix is the message role rather than an option.","solutions":["Move prefix: true to the final assistant message's provider options","Remove prefix: true from any user/system/tool messages","Check message.role === 'assistant' before attaching the prefix option"],"exampleFix":"// before\n{ role: 'user', content: 'Say hi.', providerOptions: { deepseek: { prefix: true } } }\n// after\n{ role: 'assistant', content: 'Hi!', providerOptions: { deepseek: { prefix: true } } }","handlingStrategy":"validation","validationCode":"function assertPrefixOnlyOnAssistant(messages) {\n  for (const m of messages) {\n    if (m.providerOptions?.deepseek?.prefix === true && m.role !== 'assistant') {\n      throw new Error('prefix: true is only allowed on assistant messages');\n    }\n  }\n}","typeGuard":"function isPrefixedAssistant(m): m is typeof m & { role: 'assistant' } {\n  return m.role === 'assistant' && m.providerOptions?.deepseek?.prefix === true;\n}","tryCatchPattern":"try { await generateText({ model: deepseek(model), messages }); } catch (e) { if (InvalidPromptError.isInstance(e)) { /* fix message options */ } throw e; }","preventionTips":["Only attach prefix options when message.role === 'assistant'","Build provider options per-role, not via a shared spread","Add a unit test over prompt assembly for DeepSeek prefix usage"],"tags":["deepseek","prefix-completion","invalid-prompt"],"backgroundTag":"invalid-provider-options","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}