oobabooga/textgen · error · InvalidRequestError
role: function is not supported.
Error message
role: function is not supported.
What it means
Messages with role 'function' (the legacy OpenAI mechanism for returning tool results) are rejected. The backend implements the modern tools API where results come back as role 'tool' messages with a 'tool_call_id', so the legacy role is explicitly refused with InvalidRequestError (400).
Source
Thrown at modules/api/completions.py:500
raise InvalidRequestError(message="function_call is not supported.", param='function_call')
if 'messages' not in body:
raise InvalidRequestError(message="messages is required", param='messages')
tools = None
if 'tools' in body and body['tools'] is not None and isinstance(body['tools'], list) and body['tools']:
tools = validateTools(body['tools']) # raises InvalidRequestError if validation fails
tool_choice = body.get('tool_choice', None)
if tool_choice == "none":
tools = None # Disable tool detection entirely
messages = body['messages']
for m in messages:
if 'role' not in m:
raise InvalidRequestError(message="messages: missing role", param='messages')
elif m['role'] == 'function':
raise InvalidRequestError(message="role: function is not supported.", param='messages')
# Handle multimodal content validation
content = m.get('content')
if content is None:
# OpenAI allows content: null on assistant messages when tool_calls is present
if m['role'] == 'assistant' and m.get('tool_calls'):
m['content'] = ''
else:
raise InvalidRequestError(message="messages: missing content", param='messages')
# Validate multimodal content structure
if isinstance(content, list):
for item in content:
if not isinstance(item, dict) or 'type' not in item:
raise InvalidRequestError(message="messages: invalid content item format", param='messages')
if item['type'] not in ['text', 'image_url']:
raise InvalidRequestError(message="messages: unsupported content type", param='messages')
if item['type'] == 'text' and 'text' not in item:View on GitHub (pinned to ed888c71f2)
Solutions
- Convert function results to the modern form: {"role": "tool", "tool_call_id": <id from assistant tool_calls>, "content": <result>}.
- Upgrade to the modern loop: assistant message carries 'tool_calls', the tool reply uses role 'tool'.
- Upgrade the OpenAI SDK to >=1.0, which emits role 'tool' natively.
Example fix
# before
messages.append({"role": "function", "name": "get_weather", "content": "21C"})
# after
messages.append({"role": "tool", "tool_call_id": assistant_msg["tool_calls"][0]["id"], "content": "21C"}) Defensive patterns
Strategy: validation
Validate before calling
def migrate_function_roles(messages):
out = []
for m in messages:
if m.get('role') == 'function':
out.append({'role': 'tool', 'tool_call_id': m.get('tool_call_id', m.get('name', 'call_0')), 'content': m.get('content', '')})
else:
out.append(m)
return out Type guard
def has_legacy_function_role(messages) -> bool:
return any(isinstance(m, dict) and m.get('role') == 'function' for m in messages) Try / catch
try:
resp = client.chat.completions.create(model=m, messages=msgs)
except openai.BadRequestError as e:
if 'role: function is not supported' in str(e):
msgs = migrate_function_roles(msgs)
resp = client.chat.completions.create(model=m, messages=msgs)
else:
raise Prevention
- Use the modern loop: assistant tool_calls -> role 'tool' replies with tool_call_id.
- Upgrade to openai>=1.0 SDK.
- Add a pre-send lint that rejects role 'function'.
When it happens
Trigger: POST /v1/chat/completions with a message {"role": "function", "name": "get_weather", "content": "..."}. Typically sent by old OpenAI SDK versions after executing a function call, or by hand-rolled agent loops following 2023 tutorials.
Common situations: Old openai<1.0 SDK chat loops; agent frameworks not yet migrated to the tools API; mixing a legacy client with the modern backend after fixing only 'functions'/'function_call'.
Related errors
- functions is not supported.
- function_call is not supported.
- messages is required
- messages: missing role
- messages: missing content
AI-assisted analysis of oobabooga/textgen@ed888c71f2 (2026-08-15).
Data as JSON: /api/errors/fc3ccd8c50f53db6.
Report an issue: GitHub.