ValueError
openai.error.ValueError
Stack trace
ValueError: Expected finish_reason to be 'tool_calls' but got 'stop'
File "app.py", line 42, in call_function
if response.choices[0].finish_reason != 'tool_calls':
ValueError: Expected finish_reason to be 'tool_calls' but got 'stop' Why it happens
When using OpenAI's function calling, the finish_reason field indicates why the model stopped generating. If the model does not invoke a function call, finish_reason will be 'stop' or another value instead of 'tool_calls'. This mismatch causes code expecting 'tool_calls' to raise an error.
Detection
Check the finish_reason field in the response before processing function call data. Log unexpected finish_reason values to catch this early.
Causes & fixes
The model did not trigger a function call, so finish_reason is 'stop' instead of 'tool_calls'.
Add logic to handle finish_reason values other than 'tool_calls' gracefully, such as skipping function call processing or retrying.
Incorrect assumptions in code that finish_reason will always be 'tool_calls' when function calling is enabled.
Validate finish_reason explicitly and add fallback handling for cases when the model returns normal text completion.
Using a base model or prompt that does not reliably trigger function calls.
Use instruction-tuned models like gpt-4o or gpt-4o-mini and ensure prompt clearly requests function calls.
Code: broken vs fixed
from openai import OpenAI
import os
client = OpenAI(api_key=os.environ['OPENAI_API_KEY'])
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Call the function"}],
functions=[{"name": "my_func", "parameters": {}}],
function_call="auto"
)
# This line causes error if finish_reason is not 'tool_calls'
if response.choices[0].finish_reason != 'tool_calls': # triggers ValueError
raise ValueError(f"Expected finish_reason to be 'tool_calls' but got {response.choices[0].finish_reason}")
func_call = response.choices[0].message.function_call
print(func_call) from openai import OpenAI
import os
client = OpenAI(api_key=os.environ['OPENAI_API_KEY'])
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Call the function"}],
functions=[{"name": "my_func", "parameters": {}}],
function_call="auto"
)
# Fix: Check finish_reason before accessing function_call
if response.choices[0].finish_reason == 'tool_calls':
func_call = response.choices[0].message.function_call
print(func_call)
else:
print(f"No function call triggered, finish_reason: {response.choices[0].finish_reason}") Workaround
Wrap the function call access in try/except ValueError and fallback to normal message content if finish_reason is not 'tool_calls'.
Prevention
Design your code to handle all possible finish_reason values from the OpenAI API and use instruction-tuned models with clear prompts to reliably trigger function calls.