openai/openai-python · error · ValueError
Expected a non-empty value for `thread_id` but received {thr
Error message
Expected a non-empty value for `thread_id` but received {thread_id!r} What it means
client.beta.threads.messages.create() requires a non-empty thread_id because it is a path parameter for POST /threads/{thread_id}/messages. The SDK validates this client-side and raises ValueError before making any HTTP request, since an empty id would build a malformed URL.
Source
Thrown at src/openai/resources/beta/threads/messages.py:98
attachments: A list of files attached to the message, and the tools they should be added to.
metadata: Set of 16 key-value pairs that can be attached to an object. This can be useful
for storing additional information about the object in a structured format, and
querying for objects via API or the dashboard.
Keys are strings with a maximum length of 64 characters. Values are strings with
a maximum length of 512 characters.
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
extra_body: Add additional JSON properties to the request
timeout: Override the client-level default timeout for this request, in seconds
"""
if not thread_id:
raise ValueError(f"Expected a non-empty value for `thread_id` but received {thread_id!r}")
extra_headers = {"OpenAI-Beta": "assistants=v2", **(extra_headers or {})}
return self._post(
path_template("/threads/{thread_id}/messages", thread_id=thread_id),
body=maybe_transform(
{
"content": content,
"role": role,
"attachments": attachments,
"metadata": metadata,
},
message_create_params.MessageCreateParams,
),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
security={"bearer_auth": True},View on GitHub (pinned to 9917c6e28e)
Solutions
- Create the thread first and pass its id: thread = client.beta.threads.create(); client.beta.threads.messages.create(thread_id=thread.id, ...)
- Verify the variable actually holds a string id, not an object or None
- Validate ids from external input before calling the API
Example fix
# before client.beta.threads.messages.create(thread_id="", content="hi", role="user") # after thread = client.beta.threads.create() client.beta.threads.messages.create(thread_id=thread.id, content="hi", role="user")
Defensive patterns
Strategy: validation
Validate before calling
if not thread_id:
raise ValueError("thread_id is required; create the thread first")
client.beta.threads.messages.create(thread_id=thread_id, role="user", content="hi") Type guard
def has_thread_id(t: object) -> bool:
return isinstance(t, str) and bool(t.strip()) Prevention
- Create the thread before adding messages
- Type thread ids as str, not Optional[str], wherever they flow
When it happens
Trigger: Calling client.beta.threads.messages.create(thread_id="", ...) or passing None/an unassigned variable as thread_id.
Common situations: Creating a message before creating the thread (no id yet), storing the wrong field (passing the Thread object or the message instead of thread.id), or ids loaded from empty config/env values.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- Expected a non-empty value for `message_id` but received {me
- Expected a non-empty value for `thread_id` but received {thr
- Expected a non-empty value for `thread_id` but received {thr
- Expected a non-empty value for `run_id` but received {run_id
- Expected a non-empty value for `thread_id` but received {thr
AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28).
Data as JSON: /api/errors/440b1f2436776cf4.
Report an issue: GitHub.