Примечание автора: Подробное объяснение 6 распространённых причин ошибки 400 required oneof field data must have one initialized field при вызове изображений Gemini, таких как gemini-3.1-flash-image-preview, и соответствующие способы их исправления.

При вызове моделей 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] из сообщения об ошибке точно определить место проблемы и последовательно проверить все 6 причин. Обычно на исправление уходит не более 5 минут.
Основной анализ ошибки "required oneof field data" в моделях изображений Gemini
| Ключевой момент | Объяснение | Направление проверки |
|---|---|---|
| Суть ошибки | В массиве parts присутствуют пустые или некорректно сформированные элементы |
Проверьте каждый элемент в contents[].parts[] |
| Ключевая подсказка | parts[2] указывает на 3-й элемент (отсчёт с 0) |
Напрямую перейдите к соответствующему элементу part |
| Тип ошибки | 400 INVALID_ARGUMENT, ошибка на стороне клиента | Не исправится автоматически, необходимо изменить код |
| Область воздействия | Общая для всех моделей изображений Gemini | Применимо к NB2, NB Pro, Gemini Flash |
| Сложность исправления | Низкая, обычно проблема в формате | Достаточно исправить в соответствии с правильным форматом |
Расшифровка структуры сообщения об ошибке в моделях изображений Gemini
Давайте разберём структуру сообщения об ошибке — это ключ к локализации проблемы:
GenerateContentRequest.contents[0].parts[2].data
^^^^^^^^ ^^^^^^^^
│ │
│ └── 3-й part (индексация с 0)
└── 1-й блок content
contents[0]: Указывает на первый объектcontentв теле вашего запроса.parts[2]: Указывает на 3-й элементpartвнутри этогоcontent.data: Поле данных этогоpartпустое или не было правильно инициализировано.
Логика проверки: Непосредственно проверьте в вашем коде 3-й элемент ([2]) массива parts, который находится внутри 1-го элемента ([0]) массива contents. Посмотрите, что именно вы в него передаёте.

Причина 1: В массиве parts присутствуют пустые объекты или строки
Это самая распространённая причина. В массиве запроса parts содержатся пустые элементы, такие как {}, null, пустая строка "".
| Неправильный вариант | Правильный вариант |
|---|---|
parts содержит пустой объект {} |
Каждый part должен содержать поле text или inlineData |
parts содержит {"text": ""} |
Пустой текст также вызовет ошибку, напишите хотя бы один символ |
parts содержит элемент null |
Удалите все значения null |
Неправильный код:
# ❌ parts содержит пустой объект
payload = {
"contents": [{
"parts": [
{"text": "Generate a cat image"},
{}, # ← Пустой объект, вызовет ошибку
{"text": "in watercolor style"}
]
}]
}
Правильный код:
# ✅ Каждый part содержит валидные данные
payload = {
"contents": [{
"parts": [
{"text": "Generate a cat image in watercolor style"}
]
}]
}
Как исправить: Объедините текст в один text part или убедитесь, что каждый part содержит валидные поля text или inlineData.
Причина 2: Пустые или некорректные данные base64 для изображения
При отправке запроса типа "изображение-в-изображение" данные 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: История многораундового диалога содержит пустой контент
При редактировании изображения в многораундовом диалоге, если ответ из предыдущего раунда не был обработан корректно, в историю диалога может попасть пустой блок content.
Неправильный код:
# ❌ В истории диалога присутствуют пустые parts
history = [
{"role": "user", "parts": [{"text": "Generate a logo"}]},
{"role": "model", "parts": []}, # ← Пустые parts, вызовут ошибку
{"role": "user", "parts": [{"text": "Make it blue"}]}
]
payload = {"contents": history}
Правильный код:
# ✅ Отфильтруйте пустые блоки content
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"}]}
]
# Безопасная фильтрация: удаляем записи с пустыми parts
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 |
Неправильный код:
# ❌ В REST API использован snake_case (стиль 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', последовательно проверьте каждый пункт из этого списка:

| Шаг проверки | Что проверять | Как исправить |
|---|---|---|
| Шаг 1 | Посмотрите, какой по счёту элемент в parts[N] |
Напрямую перейдите к соответствующему месту в коде |
| Шаг 2 | Пустой ли этот элемент: {}, null, "" |
Удалите пустой элемент или заполните его валидным содержимым |
| Шаг 3 | Если это inlineData, не пустой ли base64 |
Убедитесь, что файл изображения успешно прочитан |
| Шаг 4 | Содержит ли base64 префикс data: |
Удалите префикс, оставьте только чистый base64 |
| Шаг 5 | Используется ли camelCase для имён полей JSON | В REST API обязательно используйте inlineData, а не inline_data |
| Шаг 6 | Поддерживается ли формат изображения | Только PNG/JPEG/WebP/GIF |
Быстрое решение: Если вы часто сталкиваетесь с этой ошибкой на этапе разработки, рекомендую добавить функцию
validate_payload()перед отправкой запроса, чтобы автоматически проверять валидность каждого элемента в массивеparts. При вызове моделей изображений Gemini через платформу APIYI apiyi.com, формат запроса полностью соответствует официальному REST API, поэтому описанные выше методы проверки также применимы.
Правильный формат запроса для Gemini Image Models при ошибках
Правильный формат для чистого текст-в-изображение (Text-to-Image)
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))
Правильный формат для изображение-в-изображение (Image-to-Image)
Показать полный правильный код для изображение-в-изображение
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}")
Совет: Для сценариев текст-в-изображение начните с минимального формата, убедитесь, что он работает, а затем постепенно добавляйте параметры. Вызов Nano Banana 2 через платформу APIYI apiyi.com стоит $0.045 за раз, что делает отладку очень дешёвой.
Частые вопросы
В1: Что означает parts[2] в сообщении об ошибке?
parts[2] означает элемент с индексом 2 в массиве parts, то есть третий элемент (индексация начинается с 0). Просто найдите третий элемент в массиве contents[0].parts в своём коде и проверьте его содержимое. Если в вашем массиве parts всего 2 элемента (индексы 0 и 1), значит, в логике кода, возможно, случайно добавился пустой элемент при сборке массива.
В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. Но если вы напрямую вызываете REST API с помощью библиотеки requests (включая вызовы через 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:, ошибки в регистре имён полей JSON. - Для REST API обязательно используйте camelCase:
inlineData(неinline_data),mimeType(неmime_type). - Меры предосторожности: Добавьте функцию валидации полезной нагрузки перед отправкой для автоматического обнаружения пустых элементов и проблем с форматом.
Рекомендуем использовать платформу APIYI apiyi.com для вызова модели изображений Gemini при разработке и отладке. Nano Banana 2 с оплатой за использование стоит $0.045/раз, что делает стоимость отладки крайне низкой. Формат интерфейса полностью совместим с официальным REST API.
📚 Справочные материалы
-
Официальная документация по генерации изображений Gemini API: Полный формат запроса и описание параметров.
- Ссылка:
ai.google.dev/gemini-api/docs/image-generation - Описание: Содержит стандартные форматы запросов для Text-to-Image и Image-to-Image.
- Ссылка:
-
Руководство по устранению неполадок 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, чтобы ознакомиться с другими руководствами по устранению неполадок.
