apache/beam · error · IllegalArgumentException

Project and location must both be provided if one is…

Error message

Project and location must both be provided if one is provided

What it means

The GeminiModelHandler constructor validates that Vertex AI configuration is consistent. When running against Vertex AI (no API key), both a project and a location must be supplied; supplying only one is ambiguous, so the handler rejects it with this IllegalArgumentException before any client is built.

Solutions

  1. Set both project and location in the GeminiModelHandlerParameters (e.g. project="my-gcp-project", location="us-central1").
  2. If you intend to use the Gemini Developer API instead, set apiKey and remove the partial project/location config.
  3. Verify pipeline options/env vars actually populate both fields (log them before constructing the handler).

Example fix

// before
GeminiModelHandlerParameters params = GeminiModelHandlerParameters.builder().setProject("my-project").build();
// after
GeminiModelHandlerParameters params = GeminiModelHandlerParameters.builder().setProject("my-project").setLocation("us-central1").build();
Defensive patterns

Strategy: validation

Validate before calling

if (params.getApiKey() == null && ((params.getProject() == null) != (params.getLocation() == null))) { throw new IllegalArgumentException("project and location must be set together for Vertex AI"); }

Prevention

When it happens

Trigger: Constructing GeminiModelHandler with GeminiModelHandlerParameters where getProject() != null but getLocation() == null, or getLocation() != null but getProject() == null, while getApiKey() is null (Vertex AI path).

Common situations: Developers set the GCP project but forget the region (e.g. us-central1), or configure the location via env var while the project comes from pipeline options and one of them is empty. Often seen when copying examples that use the API-key path and partially switching to Vertex AI.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/bdd8932e32c762ec. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/ml/inference/gemini/src/main/java/org/apache/beam/sdk/ml/inference/gemini/GeminiModelHandler.java:60

  @Override
  public void createClient(GeminiModelParameters<InputT, OutputT> parameters) {
    if (parameters == null) {
      throw new NullPointerException("GeminiModelParameters must not be null");
    }
    this.modelParameters = parameters;

    // Configure client based on vertex or API key
    if (parameters.getApiKey() != null) {
      if (parameters.getProject() != null || parameters.getLocation() != null) {
        throw new IllegalArgumentException("Project and location must be null if API key is set");
      }
      this.client = Client.builder().apiKey(parameters.getApiKey()).build();
    } else {
      Client.Builder builder = Client.builder();
      if (parameters.getProject() != null && parameters.getLocation() != null) {
        builder.vertexAI(true).project(parameters.getProject()).location(parameters.getLocation());
      } else if (parameters.getProject() != null || parameters.getLocation() != null) {
        throw new IllegalArgumentException(
            "Project and location must both be provided if one is provided");
      }
      this.client = builder.build();
    }
  }

  @Override
  public Iterable<PredictionResult<InputT, OutputT>> request(List<InputT> input) {
    try {
      GeminiRequestFunction<InputT, OutputT> requestFn = modelParameters.getRequestFn();
      List<OutputT> responses = requestFn.apply(modelParameters.getModelName(), input, client);

      if (responses.size() != input.size()) {
        throw new IllegalStateException("Number of responses must match number of inputs");
      }

      List<PredictionResult<InputT, OutputT>> results = new ArrayList<>();
      for (int i = 0; i < input.size(); i++) {

View on GitHub (pinned to 12126d8942)