apache/beam · error · IllegalArgumentException
Project and location must be null if API key is set
Error message
Project and location must be null if API key is set
What it means
GeminiModelHandler supports two mutually exclusive auth modes: an API key (Gemini API) or Vertex AI (project + location). createClient enforces that when an API key is set, project and location must be null; otherwise this IllegalArgumentException is thrown because the two credential modes conflict.
Solutions
- Remove setProject/setLocation if you authenticate with an API key.
- Remove setApiKey and supply both project and location if you intend to use Vertex AI.
- Make your config loading conditional: only populate vertex fields when apiKey is absent (and vice versa).
Example fix
// before
params.setApiKey(key); params.setProject("my-proj"); params.setLocation("us-central1");
// after (API key mode)
params.setApiKey(key); Defensive patterns
Strategy: validation
Validate before calling
if (params.getApiKey() != null && (params.getProject() != null || params.getLocation() != null)) {
throw new IllegalArgumentException("API key mode conflicts with Vertex AI project/location");
} Type guard
boolean isConsistentAuth(GeminiModelParameters<?,?> p) { return p.getApiKey() == null ? (p.getProject() != null && p.getLocation() != null) : (p.getProject() == null && p.getLocation() == null); } Try / catch
try { handler.createClient(params); } catch (IllegalArgumentException e) { throw new IllegalStateException("Gemini auth config conflict: " + e.getMessage(), e); } Prevention
- Load auth config exclusively: if apiKey is present, skip vertex fields entirely.
- Document to operators which env vars correspond to which auth mode.
- Validate parameter combinations in unit tests before pipeline submission.
When it happens
Trigger: Building GeminiModelParameters with both setApiKey(...) and setProject(...)/setLocation(...), then calling createClient, which detects the conflicting combination.
Common situations: Copy-pasting Vertex AI config (project/location) into an API-key setup or vice versa; environment-driven config that sets all variables regardless of auth mode.
Related errors
- GeminiModelParameters must not be null
- A function must be provided to convert the input type into…
- A PValue contained in
- A schema was provided without a data format (or viceversa)…
- All inherited interfaces of
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/f7002013afdb6c80.
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:52
*/
@SuppressWarnings("nullness")
public class GeminiModelHandler<InputT extends BaseInput, OutputT extends BaseResponse>
implements BaseModelHandler<GeminiModelParameters<InputT, OutputT>, InputT, OutputT> {
private transient Client client;
private GeminiModelParameters<InputT, OutputT> modelParameters;
@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();View on GitHub (pinned to 12126d8942)