2025, Dec 14 13:00

Resolve 400 INVALID_ARGUMENT in Gemini batches.create on Vertex AI: working batch prediction setup with Google GenAI SDK and GCS

Get past 400 INVALID_ARGUMENT when calling batches.create for Gemini on Vertex AI. Upgrade google-genai, set project and region env vars, use default creds.

Batch prediction with Gemini on Vertex AI looks straightforward until a stubborn 400 INVALID_ARGUMENT blocks the run at the batches.create step. The confusing part is that even example sources like gs://cloud-samples-data/batch/prompt_for_batch_gemini_predict.jsonl or a bq:// reference can trigger the error. Below is a concise walkthrough of what causes the snag and how to get a clean run using the Google GenAI SDK with the GCS input path.

Reproducing the failure

The following snippet sets up a batch text prompt job against gemini-2.0-flash-001 and polls until completion. The call fails with 400 INVALID_ARGUMENT when invoking batches.create. The logic is minimal and uses a GCS URI for src.

import time
import os
from google import genai
from google.genai.types import CreateBatchJobConfig, JobState, HttpOptions
os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True"
ai_cli = genai.Client(
    api_key=creds.token,
    http_options=HttpOptions(api_version="v1")
)
result_uri = "gs://llm_marking_up/movie_categorization_results"
batch_job = ai_cli.batches.create(
    model="gemini-2.0-flash-001",
    src="gs://cloud-samples-data/batch/prompt_for_batch_gemini_predict.jsonl",
    config=CreateBatchJobConfig(dest=result_uri),
)
print(f"Job name: {batch_job.name}")
print(f"Job state: {batch_job.state}")
final_states = {
    JobState.JOB_STATE_SUCCEEDED,
    JobState.JOB_STATE_FAILED,
    JobState.JOB_STATE_CANCELLED,
    JobState.JOB_STATE_PAUSED,
}
while batch_job.state not in final_states:
    time.sleep(30)
    batch_job = ai_cli.batches.get(name=batch_job.name)
    print(f"Job state: {batch_job.state}")

What’s actually going wrong

The error isn’t about the JSONL file itself or the gs:// URI format. The problem is environmental: the SDK and runtime configuration must align with Vertex AI expectations. When that alignment is off, the service responds with INVALID_ARGUMENT even if the src points to a valid sample in Cloud Storage. The successful path confirms that the GCS input works once the environment is configured correctly.

Fix that unblocks batch predictions

The working setup relies on three specific actions. First, upgrade the Google GenAI SDK so the client matches current backend behavior. Second, export the required Google Cloud environment configuration so Vertex AI knows which project and region to use. Third, use GCP default credential authentication and omit the api_key when creating the client.

pip install --upgrade google-genai
export GOOGLE_CLOUD_PROJECT=your_project_id
export GOOGLE_CLOUD_LOCATION=us-central1
export GOOGLE_GENAI_USE_VERTEXAI=True

With that in place, the Python code becomes minimal and stable. The logic remains the same: create a batch job against gemini-2.0-flash-001 with a GCS JSONL source and poll until a terminal state.

import time
import os
from google import genai
from google.genai.types import CreateBatchJobConfig, JobState, HttpOptions
os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True"
ai_cli = genai.Client(
    http_options=HttpOptions(api_version="v1")
)
result_uri = "gs://llm_marking_up/movie_categorization_results"
batch_job = ai_cli.batches.create(
    model="gemini-2.0-flash-001",
    src="gs://cloud-samples-data/batch/prompt_for_batch_gemini_predict.jsonl",
    config=CreateBatchJobConfig(dest=result_uri),
)
print(f"Job name: {batch_job.name}")
print(f"Job state: {batch_job.state}")
final_states = {
    JobState.JOB_STATE_SUCCEEDED,
    JobState.JOB_STATE_FAILED,
    JobState.JOB_STATE_CANCELLED,
    JobState.JOB_STATE_PAUSED,
}
while batch_job.state not in final_states:
    time.sleep(30)
    batch_job = ai_cli.batches.get(name=batch_job.name)
    print(f"Job state: {batch_job.state}")

A successful run prints the job transitions and ends with JOB_STATE_SUCCEEDED, and the result file batch_prompt_for_batch_gemini_predict.jsonl appears in the specified GCS bucket.

Job name: projects/xxx/locations/us-central1/batchPredictionJobs/xxx
Job state: JOB_STATE_PENDING
Job state: JOB_STATE_RUNNING
...
Job state: JOB_STATE_SUCCEEDED

Why this matters for Vertex AI batch workloads

Batch prediction pipelines for generative models are sensitive to SDK versions and project scoping. Ensuring the SDK is current and the environment specifies GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION prevents opaque request validation failures. Using default credentials keeps the client setup consistent with Google Cloud’s authentication flow, which avoids mismatched configuration between API keys and Vertex AI settings.

Takeaways

If batches.create returns 400 INVALID_ARGUMENT for a Gemini batch job, align the SDK and environment before chasing data format issues. Upgrade google-genai, export GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION, set GOOGLE_GENAI_USE_VERTEXAI=True, and use GCP default credentials. With that combination, the documented GCS input like gs://cloud-samples-data/batch/prompt_for_batch_gemini_predict.jsonl runs as expected and writes outputs to your bucket.