title: "حل خطأ 400 'required oneof field data must have one initialized field' عند استدعاء نماذج Gemini للصور"
description: "دليل مفصل لستة أسباب شائعة لخطأ 400 عند استخدام gemini-3.1-flash-image-preview و gemini-3.0-pro-image، مع حلول عملية لكل حالة."
date: 2024-12-20
category: "برمجة"
tags: ["Gemini", "Google AI", "نماذج لغة كبيرة", "توليد الصور", "استكشاف الأخطاء وإصلاحها"]

عند استدعاء gemini-3.1-flash-image-preview (Nano Banana 2) أو gemini-3.0-pro-image (Nano Banana Pro) لتوليد الصور، يواجه العديد من المطورين هذا الخطأ المحير 400:
{
"status_code": 400,
"error": {
"message": "* GenerateContentRequest.contents[0].parts[2].data: required oneof field 'data' must have one initialized field",
"type": "upstream_error",
"code": 400
}
}
المعنى الأساسي لهذا الخطأ هو: حقل data في أحد عناصر parts في جسم الطلب الذي أرسلته فارغ أو تنسيقه غير صحيح. خطأ 400 هو خطأ في معاملات العميل، ولن يتم إصلاحه تلقائيًا، ويجب تصحيح الكود لحله.
يستعرض هذا المقال 6 أسباب شائعة تؤدي إلى هذا الخطأ، مع مقارنة بين الكود الخاطئ والصحيح لكل حالة، لمساعدتك في تحديد المشكلة وإصلاحها بسرعة.
القيمة الأساسية: بعد قراءة هذا المقال، يمكنك استخدام رقم الفهرس parts[N] في رسالة الخطأ لتحديد موقع المشكلة بدقة، والتحقق من الأسباب الستة واحدًا تلو الآخر، وعادةً ما يمكنك إصلاح المشكلة في غضون 5 دقائق.
تحليل أساسي لخطأ "required oneof field data" في نموذج الصور Gemini
| النقطة | الشرح | اتجاه التحقق |
|---|---|---|
| جوهر الخطأ | وجود عناصر فارغة أو ذات تنسيق خاطئ في مصفوفة parts |
تحقق من كل عنصر في contents[].parts[] |
| دليل رئيسي | parts[2] تشير إلى العنصر الثالث (الترقيم يبدأ من 0) |
حدد موقع الـ part المقابل مباشرةً |
| نوع الخطأ | 400 INVALID_ARGUMENT، خطأ من جانب العميل | لا يتم استعادته تلقائيًا، يجب تعديل الكود |
| نطاق التأثير | ينطبق على جميع نماذج صور Gemini | NB2 و NB Pro و Gemini Flash جميعها مشمولة |
| صعوبة الإصلاح | منخفضة، عادةً ما تكون مشكلة في التنسيق | قم بالتعديل وفقًا للتنسيق الصحيح |
تفسير بنية رسالة الخطأ في نموذج صور Gemini
دعنا نحلل بنية رسالة الخطأ، فهذا هو المفتاح لتحديد المشكلة:
GenerateContentRequest.contents[0].parts[2].data
^^^^^^^^ ^^^^^^^^
│ │
│ └── الـ part الثالث (الترقيم يبدأ من 0)
└── كتلة المحتوى الأولى
contents[0]: تشير إلى كائن المحتوى الأول في جسم الطلب الخاص بكparts[2]: تشير إلى العنصر الثالث في مصفوفة الـ parts الخاصة بهذا المحتوىdata: حقل البيانات لهذا الـ part فارغ أو لم يتم تهيئته بشكل صحيح
منهجية التحقق: تحقق مباشرةً من العنصر [2] في مصفوفة parts الخاص بالعنصر [0] في مصفوفة contents في الكود الخاص بك، لترى ما الذي تم تمريره بالضبط.

6 أسباب شائعة لأخطاء نموذج Gemini للصور وطرق إصلاحها
السبب 1: وجود كائنات فارغة أو سلاسل نصية فارغة في parts
هذا هو السبب الأكثر شيوعًا. يحتوي مصفوفة parts في الطلب على عناصر فارغة مثل {} أو null أو سلسلة نصية فارغة "".
| الطريقة الخاطئة | الطريقة الصحيحة |
|---|---|
يحتوي parts على كائن فارغ {} |
يجب أن يحتوي كل جزء على text أو inlineData |
يحتوي parts على {"text": ""} |
النص الفارغ سيؤدي أيضًا إلى خطأ، اكتب حرفًا واحدًا على الأقل |
يحتوي parts على عنصر null |
قم بإزالة جميع قيم null |
كود خاطئ:
# ❌ يحتوي parts على كائن فارغ
payload = {
"contents": [{
"parts": [
{"text": "Generate a cat image"},
{}, # ← كائن فارغ، يؤدي إلى خطأ
{"text": "in watercolor style"}
]
}]
}
كود صحيح:
# ✅ كل جزء يحتوي على محتوى صالح
payload = {
"contents": [{
"parts": [
{"text": "Generate a cat image in watercolor style"}
]
}]
}
نقاط الإصلاح: قم بدمج النص في جزء text واحد، أو تأكد من أن كل جزء يحتوي على حقول text أو inlineData صالحة.
السبب 2: بيانات base64 للصورة فارغة أو ذات تنسيق خاطئ
عند إرسال طلب تحويل صورة إلى صورة (image-to-image)، قد تكون بيانات base64 في inlineData فارغة أو تالفة أو ذات تنسيق غير صحيح.
كود خاطئ:
# ❌ بيانات base64 تحتوي على بادئة data URI
payload = {
"contents": [{
"parts": [
{
"inlineData": {
"mimeType": "image/png",
"data": "data:image/png;base64,iVBORw0KGgo..." # ← لا ينبغي أن تحتوي على البادئة
}
},
{"text": "Change the background to blue"}
]
}]
}
# ❌ بيانات base64 عبارة عن سلسلة نصية فارغة
"inlineData": {
"mimeType": "image/jpeg",
"data": "" # ← بيانات فارغة، تؤدي مباشرة إلى خطأ
}
كود صحيح:
import base64
import pathlib
# ✅ قراءة الصورة بشكل صحيح وتحويلها إلى base64 خالص
image_bytes = pathlib.Path("input.png").read_bytes()
image_b64 = base64.b64encode(image_bytes).decode("utf-8")
payload = {
"contents": [{
"parts": [
{
"inlineData": {
"mimeType": "image/png",
"data": image_b64 # ← سلسلة base64 خالصة، بدون بادئة
}
},
{"text": "Change the background to blue"}
]
}]
}
نقاط الإصلاح:
- حقل
dataيقبل فقط سلسلة base64 خالصة، ولا يجب أن يحتوي على البادئةdata:image/png;base64, - تأكد من وجود ملف الصورة فعليًا وتمت قراءته بنجاح، وتجنب تمرير سلسلة نصية فارغة
- يجب أن يتطابق
mimeTypeمع تنسيق الصورة الفعلي (image/png،image/jpeg،image/webp)
السبب 3: لم يتم تحويل كائن File بشكل صحيح إلى مرجع محتوى
بعد تحميل ملف باستخدام Files API في Google GenAI SDK، قد يؤدي تمرير كائن File مباشرة إلى contents إلى فشل SDK في التحويل بشكل صحيح.
كود خاطئ:
from google import genai
client = genai.Client(api_key="YOUR_KEY")
# تحميل الملف
file = client.files.upload(file="photo.png")
# ❌ في بعض إصدارات SDK، قد يفشل تمرير كائن File مباشرة
response = client.models.generate_content(
model="gemini-3.1-flash-image-preview",
contents=["Edit this image", file] # ← قد لا يتم تحويل كائن File تلقائيًا
)
كود صحيح:
from google import genai
from google.genai import types
client = genai.Client(api_key="YOUR_KEY")
# تحميل الملف
file = client.files.upload(file="photo.png")
# ✅ الطريقة 1: إنشاء مرجع ملف يدويًا
response = client.models.generate_content(
model="gemini-3.1-flash-image-preview",
contents=[
types.Content(parts=[
types.Part(file_data=types.FileData(file_uri=file.uri, mime_type=file.mime_type)),
types.Part(text="Edit this image: change background to sunset")
])
],
config=types.GenerateContentConfig(
response_modalities=["TEXT", "IMAGE"]
)
)
# ✅ الطريقة 2: استخدام inlineData لتمرير base64 مباشرة (أكثر موثوقية)
import base64, pathlib
image_b64 = base64.b64encode(pathlib.Path("photo.png").read_bytes()).decode()
response = client.models.generate_content(
model="gemini-3.1-flash-image-preview",
contents=[
types.Content(parts=[
types.Part(inline_data=types.Blob(mime_type="image/png", data=image_b64)),
types.Part(text="Edit this image: change background to sunset")
])
],
config=types.GenerateContentConfig(
response_modalities=["TEXT", "IMAGE"]
)
)
نقاط الإصلاح: يوصى باستخدام طريقة inlineData + base64 لتمرير بيانات الصورة مباشرة، فهي أكثر استقرارًا وموثوقية من Files API.
السبب 4: يحتوي سجل المحادثة متعدد الجولات على محتوى فارغ
عند تحرير الصور في محادثة متعددة الجولات، إذا لم تتم معالجة استجابة الجولة السابقة بشكل صحيح، فقد يحتوي سجل المحادثة على كتل محتوى فارغة.
كود خاطئ:
# ❌ يحتوي سجل المحادثة على أجزاء فارغة
history = [
{"role": "user", "parts": [{"text": "Generate a logo"}]},
{"role": "model", "parts": []}, # ← أجزاء فارغة، تؤدي إلى خطأ
{"role": "user", "parts": [{"text": "Make it blue"}]}
]
payload = {"contents": history}
كود صحيح:
# ✅ تصفية كتل المحتوى الفارغة
history = [
{"role": "user", "parts": [{"text": "Generate a logo"}]},
{"role": "model", "parts": [{"text": "Here is the logo I generated."}]},
{"role": "user", "parts": [{"text": "Make it blue"}]}
]
# تصفية آمنة: إزالة السجلات التي تكون أجزاؤها فارغة
clean_history = [msg for msg in history if msg.get("parts") and len(msg["parts"]) > 0]
payload = {"contents": clean_history}
نقاط الإصلاح: قبل إرسال الطلب، قم باجتياز مصفوفة contents وقم بتصفية جميع العناصر التي تكون parts عبارة عن قائمة فارغة أو تحتوي على كائنات فارغة.
السبب 5: خطأ في حالة أحرف أسماء حقول JSON في طلب REST API
تستخدم أسماء حقول JSON في Gemini API camelCase (تسمية الجمل)، وهي حساسة لحالة الأحرف. يؤدي الخطأ في كتابة اسم الحقل إلى تجاهل هذا الحقل، مما يعادل تمرير بيانات فارغة.
| اسم الحقل الخاطئ | اسم الحقل الصحيح | الشرح |
|---|---|---|
inline_data |
inlineData |
REST API تستخدم camelCase |
mime_type |
mimeType |
REST API تستخدم camelCase |
file_uri |
fileUri |
REST API تستخدم camelCase |
response_modalities |
responseModalities |
REST API تستخدم camelCase |
image_config |
imageConfig |
REST API تستخدم camelCase |
aspect_ratio |
aspectRatio |
REST API تستخدم camelCase |
image_size |
imageSize |
REST API تستخدم camelCase |
كود خاطئ:
# ❌ استخدام snake_case في REST API (أسلوب Python SDK)
payload = {
"contents": [{
"parts": [{
"inline_data": { # ← يجب أن يكون inlineData
"mime_type": "image/png", # ← يجب أن يكون mimeType
"data": image_b64
}
}]
}],
"generation_config": { # ← يجب أن يكون generationConfig
"response_modalities": ["IMAGE"] # ← يجب أن يكون responseModalities
}
}
كود صحيح:
# ✅ REST API تستخدم camelCase
payload = {
"contents": [{
"parts": [{
"inlineData": {
"mimeType": "image/png",
"data": image_b64
}
}]
}],
"generationConfig": {
"responseModalities": ["IMAGE"],
"imageConfig": {
"aspectRatio": "1:1",
"imageSize": "2K"
}
}
}
🎯 ملاحظة مهمة: Python SDK (
google-genai) يستخدمsnake_case(مثلinline_data)، بينما الاستدعاء المباشر لـ REST API يستخدمcamelCase(مثلinlineData). عند الاستدعاء عبر منصات وسيطة مثل APIYI apiyi.com، يتم استخدام تنسيق REST API، ويجب استخدام camelCase.
السبب 6: تنسيق الصورة غير مدعوم أو الملف تالف
بيانات base64 للصورة موجودة، لكن تنسيق الصورة نفسه غير مدعوم أو أن الملف تالف.
تنسيقات الإدخال المدعومة في نموذج Gemini للصور:
| التنسيق | mimeType | حالة الدعم |
|---|---|---|
| PNG | image/png |
مدعوم |
| JPEG | image/jpeg |
مدعوم |
| WebP | image/webp |
مدعوم |
| GIF | image/gif |
مدعوم جزئيًا (الإطار الأول فقط) |
| BMP | image/bmp |
غير مدعوم |
| SVG | image/svg+xml |
غير مدعوم |
| TIFF | image/tiff |
غير مدعوم |
طريقة التحقق:
import base64
# التحقق مما إذا كانت بيانات base64 صالحة
def validate_image_data(b64_string, mime_type):
# 1. التحقق من عدم كونها فارغة
if not b64_string:
print("ERROR: base64 data is empty")
return False
# 2. التحقق مما إذا كانت تحتوي على بادئة data URI
if b64_string.startswith("data:"):
print("ERROR: Remove 'data:image/...;base64,' prefix")
return False
# 3. التحقق مما إذا كان يمكن فك تشفير base64
try:
decoded = base64.b64decode(b64_string)
print(f"OK: Decoded size = {len(decoded)} bytes")
except Exception as e:
print(f"ERROR: Invalid base64 - {e}")
return False
# 4. التحقق مما إذا كان mimeType مدعومًا
supported = ["image/png", "image/jpeg", "image/webp", "image/gif"]
if mime_type not in supported:
print(f"ERROR: Unsupported mimeType '{mime_type}'")
return False
print("PASS: Image data is valid")
return True
💡 اقتراح: إضافة دالة التحقق من البيانات قبل إرسال الطلب يمكن أن تكتشف معظم مشاكل التنسيق مسبقًا. ينطبق هذا أيضًا عند الاستدعاء عبر منصة APIYI apiyi.com.
قائمة فحص كاملة لأخطاء نموذج الصور Gemini
عند مواجهتك خطأ required oneof field 'data'، اتبع هذه القائمة خطوة بخطوة للفحص:

| خطوة الفحص | ما يجب التحقق منه | طريقة الإصلاح |
|---|---|---|
| Step 1 | تحقق من الفهرس N في parts[N] |
حدد الموقع المقابل في الكود مباشرة |
| Step 2 | هل العنصر {} أو null أو ""؟ |
أزل العنصر الفارغ أو املأه بمحتوى صالح |
| Step 3 | إذا كان inlineData، هل بيانات base64 فارغة؟ |
تأكد من قراءة ملف الصورة بنجاح |
| Step 4 | هل تحتوي بيانات base64 على بادئة data:؟ |
أزل البادئة، احتفظ ببيانات base64 النقية فقط |
| Step 5 | هل أسماء حقول JSON تستخدم camelCase؟ | واجهة REST API تتطلب inlineData وليس inline_data |
| Step 6 | هل تنسيق الصورة مدعوم؟ | PNG/JPEG/WebP/GIF فقط |
إصلاح سريع: إذا واجهت هذا الخطأ بشكل متكرر أثناء مرحلة التطوير، ننصح بإضافة دالة
validate_payload()قبل إرسال الطلب، للتحقق تلقائيًا من صحة كل عنصر في مصفوفةparts. عند استدعاء نموذج صور Gemini عبر منصة APIYI apiyi.com، يكون تنسيق الطلب مطابقًا تمامًا لواجهة REST API الرسمية، وتنطق طرق الفحص المذكورة أعلاه أيضًا.
أخطاء نموذج الصور Gemini: تنسيق الطلب الصحيح
التنسيق الصحيح لتحويل النص إلى صورة
import requests, base64
API_KEY = "your-apiyi-api-key"
ENDPOINT = "https://api.apiyi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent"
# ✅ التنسيق الصحيح الأبسط
payload = {
"contents": [{
"parts": [
{"text": "A cute orange cat sitting on a windowsill, watercolor style, 4K"}
]
}],
"generationConfig": {
"responseModalities": ["IMAGE"],
"imageConfig": {
"aspectRatio": "1:1",
"imageSize": "2K"
}
}
}
response = requests.post(
ENDPOINT,
headers={"Content-Type": "application/json", "x-goog-api-key": API_KEY},
json=payload,
timeout=120
)
result = response.json()
image_data = result["candidates"][0]["content"]["parts"][0]["inlineData"]["data"]
with open("output.png", "wb") as f:
f.write(base64.b64decode(image_data))
التنسيق الصحيح لتحويل صورة إلى صورة
عرض الكود الكامل الصحيح لتحويل صورة إلى صورة
import requests
import base64
import pathlib
API_KEY = "your-apiyi-api-key"
ENDPOINT = "https://api.apiyi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent"
# قراءة الصورة الأصلية وتحويلها إلى base64 خالص
image_path = pathlib.Path("input_photo.png")
if not image_path.exists():
raise FileNotFoundError(f"Image not found: {image_path}")
image_bytes = image_path.read_bytes()
image_b64 = base64.b64encode(image_bytes).decode("utf-8")
# التحقق من البيانات
assert len(image_b64) > 0, "Base64 data is empty"
assert not image_b64.startswith("data:"), "Remove data URI prefix"
# ✅ تنسيق الطلب الصحيح لتحويل صورة إلى صورة
payload = {
"contents": [{
"parts": [
{
"inlineData": {
"mimeType": "image/png",
"data": image_b64
}
},
{
"text": "Change the background to a sunset beach scene, keep the subject unchanged"
}
]
}],
"generationConfig": {
"responseModalities": ["IMAGE"],
"imageConfig": {
"aspectRatio": "1:1",
"imageSize": "2K"
}
}
}
response = requests.post(
ENDPOINT,
headers={"Content-Type": "application/json", "x-goog-api-key": API_KEY},
json=payload,
timeout=120
)
if response.status_code == 200:
result = response.json()
output_data = result["candidates"][0]["content"]["parts"][0]["inlineData"]["data"]
with open("output_edited.png", "wb") as f:
f.write(base64.b64decode(output_data))
print("Success! Image saved.")
else:
print(f"Error {response.status_code}: {response.text}")
اقتراح: في سيناريوهات تحويل النص إلى صورة، ننصح بالبدء بالتنسيق الأبسط، والتأكد من نجاح التشغيل قبل إضافة المعاملات تدريجيًا. من خلال منصة APIYI apiyi.com لاستدعاء Nano Banana 2، يتم الدفع حسب الاستخدام بمعدل $0.045 لكل طلب، مما يجعل تكلفة مرحلة التصحيح منخفضة جدًا.
الأسئلة الشائعة
س1: ماذا يعني parts[2] في رسالة الخطأ؟
يشير parts[2] إلى العنصر ذي الفهرس 2 في مصفوفة parts، أي العنصر الثالث (يبدأ الفهرس من 0). ما عليك سوى تحديد العنصر الثالث في مصفوفة contents[0].parts في كودك وفحص محتواه. إذا كانت مصفوفة parts تحتوي على عنصرين فقط (الفهرس 0 و 1)، فهذا يعني أن منطق الكود ربما أضاف عنصرًا فارغًا عن طريق الخطأ أثناء تجميع parts.
س2: هل يمكن مواجهة هذا الخطأ عند الاستدعاء عبر APIYI؟
نعم. تعمل APIYI apiyi.com كمنصة وسيطة، حيث تنقل طلبك إلى خادم Gemini الخلفي. إذا كان هناك مشكلة في تنسيق جسم الطلب نفسه، فسيعيد الخادم الخلفي نفس خطأ 400. لا تقوم APIYI بتعديل هيكل جسم طلبك، لذا فإن مسؤولية التأكد من صحة تنسيق الطلب تقع على عاتق المطور. الخبر السار هو أن طريقة الإصلاح هي نفسها تمامًا عند الاستدعاء المباشر لـ Google API.
س3: لماذا تختلف أسماء الحقول بين Python SDK و REST API؟
يتبع Google GenAI Python SDK اصطلاح تسمية snake_case الخاص بـ Python (مثل inline_data، mime_type)، حيث يقوم SDK تلقائيًا بتحويلها إلى camelCase الذي يتطلبه API. ولكن إذا استخدمت مكتبة requests لاستدعاء REST API مباشرة (بما في ذلك عبر APIYI apiyi.com)، فيجب عليك استخدام تنسيق camelCase يدويًا (مثل inlineData، mimeType)، وإلا سيتم تجاهل الحقول مما يؤدي إلى حدوث خطأ.
س4: هل هذا الخطأ هو نفسه خطأ ‘contents.parts must not be empty’؟
ليس مطابقًا تمامًا، لكن السبب مشابه. يحدث خطأ contents.parts must not be empty عندما تكون مصفوفة parts نفسها فارغة ("parts": [])، بينما يحدث خطأ required oneof field 'data' عندما يكون هناك عنصر في parts ولكن حقل البيانات الخاص بهذا العنصر غير مهيأ (مثل "parts": [{}]). فكرة الإصلاح واحدة: تأكد من أن كل part يحتوي على text أو inlineData صالح.
الخلاصة
النقاط الأساسية لخطأ required oneof field 'data' في نموذج صور Gemini:
- السبب الجذري: وجود عناصر فارغة، أو بيانات فارغة، أو عناصر ذات تنسيق خاطئ في مصفوفة
parts. - طريقة التحديد: تحديد الموقع في الكود مباشرةً باستخدام رقم الفهرس
parts[N]الموجود في رسالة الخطأ. - السبب الأكثر شيوعاً: كائن فارغ
{}، أو بيانات base64 تحتوي على بادئةdata:، أو خطأ في حالة أحرف (Case) اسم حقل JSON. - واجهة REST API تستخدم camelCase إلزامياً:
inlineData(وليسinline_data)،mimeType(وليسmime_type). - إجراءات الوقاية: إضافة دالة للتحقق من payload قبل الإرسال، للكشف التلقائي عن العناصر الفارغة ومشاكل التنسيق.
يوصى باستخدام منصة APIYI apiyi.com لاستدعاء نموذج صور Gemini لأغراض التطوير والتصحيح، حيث أن خدمة Nano Banana 2 تتكلف $0.045 لكل استدعاء، مما يجعل تكلفة التصحيح منخفضة جداً، كما أن تنسيق الواجهة متوافق تماماً مع REST API الرسمي.
📚 المراجع
-
الوثائق الرسمية لتوليد الصور في Gemini API: تنسيق الطلب الكامل وشرح المعاملات.
- الرابط:
ai.google.dev/gemini-api/docs/image-generation - الشرح: يتضمن تنسيق الطلب القياسي لتحويل النص إلى صورة وتحويل الصورة إلى صورة.
- الرابط:
-
دليل استكشاف الأخطاء وإصلاحها في Gemini API: رموز الأخطاء الرسمية واقتراحات الإصلاح.
- الرابط:
ai.google.dev/gemini-api/docs/troubleshooting - الشرح: يغطي طرق استكشاف الأخطاء الشائعة مثل 400 و429 و500.
- الرابط:
-
GitHub Issue: مناقشة خطأ required oneof field data: تقارير المجتمع وحلول الإصلاح.
- الرابط:
github.com/google-gemini/cookbook/issues/786 - الشرح: يتضمن تحليلاً مفصلاً وحلاً بديلاً (workaround) لهذا الخطأ الناتج عن تمرير كائن File.
- الرابط:
-
وثائق دمج APIYI Nano Banana 2: دليل كامل لاستدعاء نموذج صور Gemini عبر منصة APIYI.
- الرابط:
docs.apiyi.com/en/api-capabilities/nano-banana-2-image - الشرح: يتضمن أمثلة على تنسيق الطلب الصحيح وإجابات للأسئلة الشائعة.
- الرابط:
المؤلف: فريق APIYI التقني
التواصل التقني: إذا واجهت مشكلة في استدعاء Gemini API، نرحب بك لزيارة مركز الوثائق APIYI docs.apiyi.com لمشاهدة المزيد من أدلة استكشاف الأخطاء.
