{"record":{"id":"d90ef32e166506b4","repo":"apache/beam","slug":"index-out-of-bounds-for-positional-parameter-index","errorCode":null,"errorMessage":"Index out of bounds for positional parameter: ${index}","messagePattern":"Index out of bounds for positional parameter: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/CalciteQueryPlanner.java","lineNumber":312,"sourceCode":"      return ((BeamRelNode) rel).beamComputeSelfCost(rel.getCluster().getPlanner(), bmq);\n    }\n  }\n\n  private static class ParameterBinder extends RexShuttle {\n    private final RexBuilder rexBuilder;\n    private final List<?> positionalParams;\n\n    ParameterBinder(RexBuilder rexBuilder, QueryParameters params) {\n      this.rexBuilder = rexBuilder;\n      this.positionalParams = params.getKind() == Kind.POSITIONAL ? params.positional() : null;\n    }\n\n    @Override\n    public RexNode visitDynamicParam(RexDynamicParam dynamicParam) {\n      if (positionalParams != null) {\n        int index = dynamicParam.getIndex();\n        if (index < 0 || index >= positionalParams.size()) {\n          throw new IllegalArgumentException(\n              \"Index out of bounds for positional parameter: \" + index);\n        }\n        Object val = positionalParams.get(index);\n        return makeLiteral(cleanValue(val), dynamicParam.getType());\n      }\n      return super.visitDynamicParam(dynamicParam);\n    }\n\n    private RexNode makeLiteral(Object val, RelDataType type) {\n      if (val == null) {\n        return rexBuilder.makeNullLiteral(type);\n      }\n      return rexBuilder.makeLiteral(val, type, true);\n    }\n\n    @SuppressWarnings(\"JavaUtilDate\") // explicit java.util.Date support\n    private Object cleanValue(Object value) {\n      if (value instanceof org.joda.time.ReadableInstant) {","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/CalciteQueryPlanner.java#L294-L330","documentation":"The RexShuttle visitor that substitutes positional '?' parameters into the Rex tree throws IllegalArgumentException when RexDynamicParam.getIndex() falls outside the bounds of the supplied positionalParams list. The query contains more (or invalid-indexed) positional parameters than the values provided at execution time.","triggerScenarios":"Executing a parameterized Beam SQL statement with '?' placeholders while supplying fewer Row values than the query contains (index >= positionalParams.size(), or a negative index).","commonSituations":"Adding a new '?' to the SQL but forgetting to append a corresponding value; passing parameters in the wrong order/count; mixing named and positional parameters.","solutions":["Count the '?' placeholders in the SQL and supply exactly that many positional parameter values.","Check the index in the message against the parameter list size to find the mismatch.","Use named parameters (:name) instead of positional ones to make binding explicit.","Fix the caller that builds the parameter list."],"exampleFix":"// before\nrow.withValues(\"value1\"); // query has two ?\n// after\nrow.withValues(\"value1\", \"value2\");","handlingStrategy":"validation","validationCode":"// count placeholders and compare with supplied values\nlong placeholders = sql.chars().filter(c -> c == '?').count();\nif (placeholders != values.size()) {\n  throw new IllegalArgumentException(\n      \"Query has \" + placeholders + \" ? but \" + values.size() + \" values supplied\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  return row.withValues(values.toArray());\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Index out of bounds for positional parameter\")) {\n    LOG.error(\"Positional parameter count mismatch: {}\", e.getMessage());\n  }\n  throw e;\n}","preventionTips":["Generate SQL and its parameter list from one source of truth","Prefer named parameters (:name) over positional '?'","Add a unit test asserting placeholder count equals value count","Review SQL edits that add/remove placeholders without touching values"],"tags":["sql","parameters","beam"],"backgroundTag":"index-out-of-range","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}