ValueError
ValueError: invalid detail parameter value
Stack trace
Traceback (most recent call last):
File "app.py", line 42, in <module>
response = client.chat.completions.create(
File "/path/to/site-packages/openai/_client.py", line 1234, in create
return self._post(...)
ValueError: Invalid value for 'detail': 'low'. Expected one of: 'low', 'high', 'auto'.
Or:
BadRequestError: Error code: 400 - {'error': {'message': "Invalid image detail parameter 'LOW'. Must be 'low', 'high', or 'auto'.", 'type': 'invalid_request_error', 'param': 'detail'}} Why it happens
The OpenAI vision API enforces strict validation on the detail parameter for image_url content blocks. Common mistakes include: passing uppercase values ('HIGH' instead of 'low'), using deprecated string formats, omitting the parameter entirely when it's required for certain models, or passing it in the wrong location in the message structure (top-level instead of inside the image_url object). The detail parameter must be lowercase and exist only within the image_url block, not at the message level.
Detection
Add type checking or assertion before calling the API: validate that detail is a lowercase string in ('low', 'high', 'auto') and is nested inside the image_url object, not at the message level. Log the full message structure before API calls to catch structural errors early.
Causes & fixes
detail parameter value is uppercase ('HIGH', 'LOW', 'AUTO') instead of lowercase
Convert detail to lowercase before passing: use detail.lower() or hardcode 'low', 'high', or 'auto' as lowercase strings only.
detail parameter is placed at message level instead of inside image_url object
Move detail inside the image_url dict: {"type": "image_url", "image_url": {"url": "...", "detail": "low"}}: not {"type": "image_url", "detail": "low", "image_url": {...}}
Using an unsupported detail value (typo like 'med', 'standard', 'high-res')
Use only the three valid values: 'low', 'high', or 'auto'. 'auto' is the recommended default for most use cases.
Missing detail parameter entirely when required by model or prompt
Always include detail in the image_url block. Default to 'auto' if unsure; 'auto' lets the model choose based on image complexity and token budget.
Code: broken vs fixed
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))
# BROKEN: detail is uppercase and at wrong nesting level
response = client.chat.completions.create(
model='gpt-4o',
messages=[
{
'role': 'user',
'content': [
{
'type': 'image_url',
'detail': 'HIGH', # ❌ WRONG: uppercase, wrong location
'image_url': {
'url': 'https://example.com/image.png'
}
},
{
'type': 'text',
'text': 'Describe this image in detail.'
}
]
}
]
)
print(response.choices[0].message.content) import os
from openai import OpenAI
client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))
# FIXED: detail is lowercase and nested correctly inside image_url
response = client.chat.completions.create(
model='gpt-4o',
messages=[
{
'role': 'user',
'content': [
{
'type': 'image_url',
'image_url': {
'url': 'https://example.com/image.png',
'detail': 'auto' # ✅ FIXED: lowercase, correct nesting inside image_url
}
},
{
'type': 'text',
'text': 'Describe this image in detail.'
}
]
}
]
)
print(response.choices[0].message.content) Workaround
If you cannot immediately refactor your message structure, build a validation layer that normalizes the detail parameter before API calls: use a helper function that checks detail exists and is lowercase, and reconstructs the message dict with correct nesting before passing to client.chat.completions.create(). Log the normalized structure so you can identify and fix the source code.
Prevention
Create a typed helper function or Pydantic model for vision messages that enforces valid detail values and correct nesting at the type level, preventing invalid structures from reaching the API. Use Literal['low', 'high', 'auto'] type hints and validate during message construction, not after API rejection.