BadRequestError: 400 Missing required parameter: 'role'

await openai.beta.threads.messages.create({
  thread_id: threadsCache[chatId],
  role: "user",
  content: [{ text: { value: userText } }]
});
1 Like

Good request, no error:

    user_input = input("prompt> ")  # Get input first

    thread_message = client.beta.threads.messages.create(
      thread.id,
      role="user",
      content=user_input,
    )
    print(f"Added message ID: {thread_message.id}")

You seem to be jamming some JSON-like object in instead of using positional and keyword parameters the function accepts.

Add await only if using the ascyncio client in a function.

the code was written in js(node.js), what should I do? In the regular 3.5 model, it worked perfectly.

async function chatWithOpenAI(chatId, userText) {
  try {
    console.log(`Отправляем в ChatGPT для диалога ${chatId}: ${userText}`);
    if (!threadsCache[chatId]) {
      const thread = await openai.beta.threads.create();
      threadsCache[chatId] = thread.id;
      console.log(`Создан поток ${thread.id} для диалога ${chatId}`);
    }
    
    await openai.beta.threads.messages.create({
      thread_id: threadsCache[chatId], 
      role: "user",  
      content: userText  
  });
  
    
    
    const run = await openai.beta.threads.runs.create({
      thread_id: threadsCache[chatId],
      assistant_id: ASSISTANT_ID
    });
    
    while (true) {
      const runStatus = await openai.beta.threads.runs.retrieve({
        thread_id: threadsCache[chatId],
        run_id: run.id
      });
      const status = runStatus.status;
      if (["completed", "expired", "cancelled", "failed"].includes(status)) {
        console.log(`Статус выполнения для диалога ${chatId}: ${status}`);
        break;
      }
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
    
    const messagesResponse = await openai.beta.threads.messages.list({
      thread_id: threadsCache[chatId],
      before: threadAfter[threadsCache[chatId]] || undefined
    });
    
    for (const message of messagesResponse.data) {
      if (message.role === "assistant") {
        threadAfter[threadsCache[chatId]] = message.id;
        console.log(`Получен ответ для диалога ${chatId}: ${message.content[0].text.value}`);
        return message.content[0].text.value;
      }
    }
    console.log(`Ответ не получен для диалога ${chatId}`);
    return "Нет ответа от ассистента.";
    
  } catch (e) {
    console.error(`Ошибка при обращении к OpenAI для диалога ${chatId}:`, e);
    return `Ошибка: ${e}`;
  }
}
1 Like

The error you’re encountering:

BadRequestError: 400 Missing required parameter: ‘role’.

is happening because the method call to create a message in the thread is incorrect. Specifically, the method:

openai.beta.threads.messages.create()

requires two parameters:

  1. The thread ID (as the first argument)
  2. An object containing the message details (as the second argument)

As I detailed previously, in your current code, you are incorrectly passing a single object with thread_id inside it. The correct usage is to pass the thread ID as the first argument, and then the message details object as the second argument.


Step-by-step walkthrough of the mistake:

Incorrect code snippet:

await openai.beta.threads.messages.create({
  thread_id: threadsCache[chatId], 
  role: "user",  
  content: userText  
});

Why this is incorrect:

  • The method openai.beta.threads.messages.create() expects the first parameter to be the thread ID directly, not an object containing thread_id.
  • The second parameter should be an object containing the message details (role and content).

Corrected code snippet:

await openai.beta.threads.messages.create(
  threadsCache[chatId], // thread ID as first argument
  {
    role: "user",       // role as second argument object property
    content: userText   // content as second argument object property
  }
);

Additional improvements:

  • Your current implementation manually polls the run status, expecting only the statuses you show. OpenAI provides a convenient helper method createAndPoll() that simplifies this process, and new updates to the SDK library could track Assistants endpoint improvements.
  • You can simplify your code by using this helper method instead of manually polling the run status.

Final corrected and improved implementation (in your original language):

Here’s a complete, corrected, and improved version of your function:

async function chatWithOpenAI(chatId, userText) {
  try {
    console.log(`Отправляем в ChatGPT для диалога ${chatId}: ${userText}`);

    // Создаем поток, если его еще нет
    if (!threadsCache[chatId]) {
      const thread = await openai.beta.threads.create();
      threadsCache[chatId] = thread.id;
      console.log(`Создан поток ${thread.id} для диалога ${chatId}`);
    }

    // Правильно добавляем сообщение пользователя в поток
    await openai.beta.threads.messages.create(
      threadsCache[chatId], // thread ID первым аргументом
      {
        role: "user",
        content: userText
      }
    );

    // Запускаем ассистента и ждем завершения выполнения с помощью createAndPoll
    const run = await openai.beta.threads.runs.createAndPoll(
      threadsCache[chatId],
      { assistant_id: ASSISTANT_ID }
    );

    if (run.status !== 'completed') {
      console.log(`Статус выполнения для диалога ${chatId}: ${run.status}`);
      return `Ассистент не смог завершить выполнение: ${run.status}`;
    }

    // Получаем список сообщений после завершения выполнения
    const messagesResponse = await openai.beta.threads.messages.list(
      threadsCache[chatId],
      { before: threadAfter[threadsCache[chatId]] || undefined }
    );

    // Ищем последнее сообщение от ассистента
    for (const message of messagesResponse.data) {
      if (message.role === "assistant") {
        threadAfter[threadsCache[chatId]] = message.id;
        const assistantReply = message.content[0].text.value;
        console.log(`Получен ответ для диалога ${chatId}: ${assistantReply}`);
        return assistantReply;
      }
    }

    console.log(`Ответ не получен для диалога ${chatId}`);
    return "Нет ответа от ассистента.";

  } catch (e) {
    console.error(`Ошибка при обращении к OpenAI для диалога ${chatId}:`, e);
    return `Ошибка: ${e}`;
  }
}

Summary of corrections made:

  • Fixed the incorrect usage of openai.beta.threads.messages.create() by passing the thread ID as the first argument and the message details as the second argument.
  • Simplified the run polling logic by using the built-in helper method createAndPoll() provided by OpenAI’s SDK.

This corrected implementation should resolve your error and provide a cleaner, more reliable interaction with the OpenAI Assistants API.

(gpt-4.5-preview with 15k input tokens to make it a node.js Assistants expert…)

2 Likes

Thanks, it worked, I thought the problem would remain:heart_eyes:

1 Like