|

Gemini画像モデルで発生する「required oneof field data」エラーの6つの一般的な原因と修正方法

gemini-3.1-flash-image-preview(Nano Banana 2)や gemini-3.0-pro-image(Nano Banana Pro)などのGemini画像モデルを呼び出す際、多くの開発者がこの困惑を招く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
  }
}

このエラーの核心的な意味は、送信したリクエストボディ内の、ある parts 要素の data フィールドが空、またはフォーマットが正しくないということです。400エラーはクライアント側のリクエストパラメータエラーに分類され、自動的には回復せず、コードを修正する必要があります。

この記事では、このエラーを引き起こす6つの一般的な原因を整理し、それぞれに間違ったコードと正しいコードの比較を添えて、問題を迅速に特定・修正できるようにします。

核心的な価値: この記事を読めば、エラーメッセージ内の parts[N] インデックス番号を使って問題の位置を正確に特定し、6つの原因と照らし合わせて一つ一つ確認することで、通常5分以内に問題を修正できるようになります。


Gemini画像モデルのエラー「required oneof field data」の核心分析

要点 説明 調査の方向性
エラーの本質 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]:リクエストボディ内の1番目のcontentオブジェクトを指す
  • parts[2]:そのcontent内の3番目のpart要素を指す
  • data:このpartのデータフィールドが空、または正しく初期化されていない

調査の考え方:コード内の contents 配列の [0] 番目の要素の parts 配列の [2] 番目の要素を直接確認し、実際に何が渡されているのかを確認します。

Gemini 画像モデルエラー 6つのよくある原因と修正方法

原因 1: parts に空オブジェクトや空文字列が含まれている

最も一般的な原因です。 リクエストの parts 配列に {}null、空文字列 "" などの空の要素が混入しています。

間違った書き方 正しい書き方
parts{} 空オブジェクトを含む 各 part には text または inlineData が必要
parts{"text": ""} を含む 空のテキストもエラーを引き起こす、少なくとも1文字記述
partsnull 要素を含む すべての null 値を削除

エラーコード

# ❌ parts に空オブジェクトがある
payload = {
    "contents": [{
        "parts": [
            {"text": "猫の画像を生成"},
            {},                              # ← 空オブジェクト、エラー発生
            {"text": "水彩画風で"}
        ]
    }]
}

正しいコード

# ✅ 各 part に有効な内容がある
payload = {
    "contents": [{
        "parts": [
            {"text": "水彩画風で猫の画像を生成"}
        ]
    }]
}

修正ポイント:テキストを1つの text part にまとめるか、各 part に有効な text または inlineData フィールドが含まれていることを確認してください。

原因 2: 画像の base64 データが空またはフォーマットエラー

画像から画像生成(image-to-image)リクエストを送信する際、inlineData 内の base64 データが空、破損、またはフォーマットが正しくない可能性があります。

エラーコード

# ❌ base64 データに data URI プレフィックスが含まれている
payload = {
    "contents": [{
        "parts": [
            {
                "inlineData": {
                    "mimeType": "image/png",
                    "data": "data:image/png;base64,iVBORw0KGgo..."  # ← プレフィックスを含めるべきではない
                }
            },
            {"text": "背景を青に変更"}
        ]
    }]
}
# ❌ 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": "背景を青に変更"}
        ]
    }]
}

修正ポイント

  • data フィールドは純粋な base64 文字列のみ受け付けます。data:image/png;base64, のようなプレフィックスを含めないでください
  • 画像ファイルが実際に存在し、読み込みに成功していることを確認し、空文字列を渡さないようにしてください
  • mimeType は実際の画像フォーマットと一致させる必要があります(image/pngimage/jpegimage/webp

原因 3: File オブジェクトが正しくコンテンツ参照に変換されていない

Google GenAI SDK の Files API でファイルをアップロードした後、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=["この画像を編集", 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="この画像を編集: 背景を夕焼けに変更")
        ])
    ],
    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="この画像を編集: 背景を夕焼けに変更")
        ])
    ],
    config=types.GenerateContentConfig(
        response_modalities=["TEXT", "IMAGE"]
    )
)

修正ポイント:Files API よりも安定性が高い inlineData + base64 方式を使用して画像データを直接渡すことをお勧めします。

原因 4: マルチターン会話履歴に空のコンテンツが含まれている

マルチターン会話で画像を編集する際、前回の応答が正しく処理されていないと、会話履歴に空の content ブロックが混入する可能性があります。

エラーコード

# ❌ 会話履歴に空の parts が混入している
history = [
    {"role": "user", "parts": [{"text": "ロゴを生成"}]},
    {"role": "model", "parts": []},        # ← 空の parts、エラー発生
    {"role": "user", "parts": [{"text": "青くして"}]}
]

payload = {"contents": history}

正しいコード

# ✅ 空の content ブロックをフィルタリング
history = [
    {"role": "user", "parts": [{"text": "ロゴを生成"}]},
    {"role": "model", "parts": [{"text": "生成したロゴはこちらです。"}]},
    {"role": "user", "parts": [{"text": "青くして"}]}
]

# 安全なフィルタリング: parts が空リストのレコードを削除
clean_history = [msg for msg in history if msg.get("parts") and len(msg["parts"]) > 0]

payload = {"contents": clean_history}

修正ポイント:リクエストを送信する前に、contents 配列を走査し、parts が空リストまたは空オブジェクトを含むすべての要素をフィルタリングしてください。

原因 5: REST API リクエストでの JSON フィールド名の大文字小文字エラー

Gemini API の JSON フィールド名は 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 などのAPI中継サービスを通じて呼び出す場合も 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 データが空です")
        return False

    # 2. data URI プレフィックスが含まれていないかチェック
    if b64_string.startswith("data:"):
        print("ERROR: 'data:image/...;base64,' プレフィックスを削除してください")
        return False

    # 3. base64 がデコード可能かチェック
    try:
        decoded = base64.b64decode(b64_string)
        print(f"OK: デコードサイズ = {len(decoded)} バイト")
    except Exception as e:
        print(f"ERROR: 無効な base64 - {e}")
        return False

    # 4. mimeType がサポートされているかチェック
    supported = ["image/png", "image/jpeg", "image/webp", "image/gif"]
    if mime_type not in supported:
        print(f"ERROR: サポートされていない mimeType '{mime_type}' です")
        return False

    print("PASS: 画像データは有効です")
    return True

💡 推奨: リクエストを送信する前にデータ検証関数を追加すると、ほとんどのフォーマット問題を事前にキャッチできます。APIYI apiyi.com プラットフォームを通じて呼び出す場合も同様に適用されます。


Gemini 画像モデルエラー 完全なトラブルシューティングチェックリスト

required oneof field 'data' エラーが発生した場合、以下のチェックリストに従って項目ごとに調査してください:

gemini-image-api-required-oneof-field-data-error-fix-ja 图示

調査ステップ 確認内容 修正方法
Step 1 parts[N] の N が何番目の要素か確認 コード内の対応する位置を直接特定
Step 2 その part が {}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 配列の各要素が有効かどうかを自動的にチェックすることをお勧めします。APIYI apiyi.com プラットフォームを通じて Gemini 画像モデルを呼び出す場合、リクエストフォーマットは公式 REST API と完全に一致するため、上記の調査方法も同様に適用できます。


Gemini 画像モデルのエラー 正しいリクエストフォーマット参考

純粋なテキストから画像生成(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": "窓辺に座る可愛いオレンジ色の猫、水彩画風、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_path}")

image_bytes = image_path.read_bytes()
image_b64 = base64.b64encode(image_bytes).decode("utf-8")

# データの検証
assert len(image_b64) > 0, "Base64データが空です"
assert not image_b64.startswith("data:"), "data URI プレフィックスを削除してください"

# ✅ 正しい画像から画像生成のリクエストフォーマット
payload = {
    "contents": [{
        "parts": [
            {
                "inlineData": {
                    "mimeType": "image/png",
                    "data": image_b64
                }
            },
            {
                "text": "背景を夕焼けのビーチシーンに変更し、被写体はそのままにしてください"
            }
        ]
    }],
    "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("成功!画像を保存しました。")
else:
    print(f"エラー {response.status_code}: {response.text}")

推奨: テキストから画像生成の場合は、まず最もシンプルなフォーマットから始め、動作確認後にパラメータを追加していくことをお勧めします。APIYI apiyi.com プラットフォームを通じて Nano Banana 2 を呼び出す場合、1回あたり $0.045 で課金され、デバッグ段階のコストは非常に低くなります。


よくある質問

Q1: エラーメッセージの parts[2] とはどういう意味ですか?

parts[2]parts 配列内のインデックス 2 の要素、つまり3番目の要素(インデックスは0から始まります)を意味します。コード内で contents[0].parts 配列の3番目の要素を直接特定し、その内容を確認してください。もし parts 配列に要素が2つしかない(インデックス 0 と 1)場合、コードロジックで parts を結合する際に誤って空の要素が追加された可能性があります。

Q2: APIYI を通じて呼び出した場合もこのエラーに遭遇しますか?

はい、遭遇します。APIYI apiyi.com は中継プラットフォームとして、リクエストを Gemini バックエンドに転送します。リクエストボディ自体にフォーマットの問題がある場合、バックエンドは同じ 400 エラーを返します。APIYI はリクエストボディの構造を変更しないため、リクエストフォーマットが正しいことを確認するのは開発者の責任です。良いニュースは、修正方法が Google API を直接呼び出す場合と全く同じであることです。

Q3: Python SDK と REST API のフィールド名がなぜ異なるのですか?

Google GenAI Python SDK は Python の snake_case 命名規則(例: inline_datamime_type)に従っており、SDK 内部で自動的に API が要求する camelCase に変換されます。しかし、requests ライブラリを使用して REST API(APIYI apiyi.com 経由を含む)を直接呼び出す場合は、手動で camelCase フォーマット(例: inlineDatamimeType)を使用する必要があります。そうしないと、フィールドが無視されてエラーが発生します。

Q4: このエラーと contents.parts must not be empty は同じエラーですか?

完全に同じではありませんが、原因は似ています。contents.parts must not be empty は parts 配列自体が空("parts": [])の場合のエラーです。一方、required oneof field 'data' は parts に要素が存在するものの、その要素のデータフィールドが初期化されていない(例: "parts": [{}])場合のエラーです。修正の考え方は同じです:各 part が有効な text または inlineData を含んでいることを確認してください。


まとめ

Gemini画像モデル required oneof field 'data' エラーの核心ポイント:

  1. 根本原因parts 配列内に空オブジェクト、空データ、またはフォーマットエラーのある要素が存在する
  2. 特定方法:エラーメッセージ内の parts[N] インデックス番号を基に、コード内の該当箇所を直接特定する
  3. 最も一般的な原因:空オブジェクト {}data: プレフィックスを含む base64、JSONフィールド名の大文字小文字の誤り
  4. REST API は camelCase 必須inlineDatainline_data ではない)、mimeTypemime_type ではない)
  5. 予防策:送信前にペイロード検証関数を追加し、空要素やフォーマット問題を自動検出する

Gemini画像モデルの開発・デバッグには、APIYI apiyi.com プラットフォーム経由での呼び出しをお勧めします。Nano Banana 2 は従量課金制($0.045/回)でデバッグコストが非常に低く、インターフェース形式は公式 REST API と完全互換です。


📚 参考資料

  1. Gemini API 画像生成公式ドキュメント: 完全なリクエスト形式とパラメータ説明

    • リンク: ai.google.dev/gemini-api/docs/image-generation
    • 説明: Text-to-Image と Image-to-Image の標準リクエスト形式を含む
  2. Gemini API エラー調査ガイド: 公式が提供するエラーコードと修正提案

    • リンク: ai.google.dev/gemini-api/docs/troubleshooting
    • 説明: 400、429、500 などの一般的なエラーの調査方法を網羅
  3. GitHub Issue: required oneof field data エラーの議論: コミュニティからの報告と修正案

    • リンク: github.com/google-gemini/cookbook/issues/786
    • 説明: File オブジェクトの受け渡しによりこのエラーが発生する詳細な分析とワークアラウンドを含む
  4. APIYI Nano Banana 2 接続ドキュメント: APIYIプラットフォームでGemini画像モデルを呼び出す完全ガイド

    • リンク: docs.apiyi.com/en/api-capabilities/nano-banana-2-image
    • 説明: 正しいリクエスト形式のサンプルとよくある質問への回答を含む

著者: APIYI 技術チーム
技術交流: Gemini API 呼び出しで問題が発生した場合は、APIYI docs.apiyi.com ドキュメントセンターにアクセスして、より多くのトラブルシューティングガイドをご覧ください。

類似投稿