{"record":{"id":"77f01120a003d258","repo":"apache/beam","slug":"number-of-responses-must-match-number-of-inputs","errorCode":null,"errorMessage":"Number of responses must match number of inputs","messagePattern":"Number of responses must match number of inputs","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sdks/java/ml/inference/gemini/src/main/java/org/apache/beam/sdk/ml/inference/gemini/GeminiModelHandler.java","lineNumber":74,"sourceCode":"      Client.Builder builder = Client.builder();\n      if (parameters.getProject() != null && parameters.getLocation() != null) {\n        builder.vertexAI(true).project(parameters.getProject()).location(parameters.getLocation());\n      } else if (parameters.getProject() != null || parameters.getLocation() != null) {\n        throw new IllegalArgumentException(\n            \"Project and location must both be provided if one is provided\");\n      }\n      this.client = builder.build();\n    }\n  }\n\n  @Override\n  public Iterable<PredictionResult<InputT, OutputT>> request(List<InputT> input) {\n    try {\n      GeminiRequestFunction<InputT, OutputT> requestFn = modelParameters.getRequestFn();\n      List<OutputT> responses = requestFn.apply(modelParameters.getModelName(), input, client);\n\n      if (responses.size() != input.size()) {\n        throw new IllegalStateException(\"Number of responses must match number of inputs\");\n      }\n\n      List<PredictionResult<InputT, OutputT>> results = new ArrayList<>();\n      for (int i = 0; i < input.size(); i++) {\n        results.add(PredictionResult.create(input.get(i), responses.get(i)));\n      }\n      return results;\n    } catch (Exception e) {\n      throw new RuntimeException(\"Error during Gemini inference request\", e);\n    }\n  }\n}\n","sourceCodeStart":56,"sourceCodeEnd":87,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/ml/inference/gemini/src/main/java/org/apache/beam/sdk/ml/inference/gemini/GeminiModelHandler.java#L56-L87","documentation":"GeminiModelHandler.request() asserts that the request function returned exactly one response per input element. If the GeminiRequestFunction produces a response list whose size differs from the input list, the batch invariant is broken and the handler fails with this IllegalStateException rather than emitting misaligned PredictionResults.","triggerScenarios":"Calling modelHandler.request(inputs) (directly or via the results() DoFn) with a custom GeminiRequestFunction whose apply() returns fewer or more OutputT elements than the List<InputT> passed in.","commonSituations":"A custom request function that drops inputs the model refused to answer, batches internally and returns per-batch results, or returns a single aggregated response for the whole batch. Also seen when the model response parsing flattens multiple choices into one.","solutions":["Fix the custom GeminiRequestFunction so it returns exactly one OutputT per InputT in the same order.","If inputs may be skipped, keep list alignment by returning a placeholder/error OutputT for failed inputs instead of omitting them.","Add a size assertion inside the request function to catch misalignment close to the source."],"exampleFix":"// before\nreturn responses; // may have fewer entries than inputs\n// after\nif (responses.size() != inputs.size()) { /* pad or fix alignment */ }\nreturn responses;","handlingStrategy":"validation","validationCode":"List<OutputT> responses = requestFn.apply(modelName, inputs); if (responses.size() != inputs.size()) { /* realign or pad before calling handler.request */ }","typeGuard":null,"tryCatchPattern":"try { handler.request(batch); } catch (IllegalStateException e) { /* log batch sizes and realign request fn output */ }","preventionTips":["Contract-test custom GeminiRequestFunction with mock responses to enforce 1:1 mapping","Never drop failed inputs; emit placeholder outputs","Assert sizes inside the request function"],"tags":["java","batch-inference","invariant-violation"],"backgroundTag":"internal-invariant-violation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}