{"record":{"id":"8da4676cec3d962f","repo":"hibernate/hibernate-orm","slug":"positional-parameter-positionlabel-is-not","errorCode":null,"errorMessage":"Positional parameter \" + positionLabel + \" is not registered with this procedure call","messagePattern":"Positional parameter \" \\+ positionLabel \\+ \" is not registered with this procedure call","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureParameterMetadataImpl.java","lineNumber":175,"sourceCode":"\n\t@Override\n\tpublic ProcedureParameterImplementor<?> findQueryParameter(int positionLabel) {\n\t\tif ( parameters != null ) {\n\t\t\tfor ( var parameter : parameters ) {\n\t\t\t\tif ( parameter.getName() == null\n\t\t\t\t\t\t&& positionLabel == parameter.getPosition() ) {\n\t\t\t\t\treturn parameter;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic ProcedureParameterImplementor<?> getQueryParameter(int positionLabel) {\n\t\tfinal var queryParameter = findQueryParameter( positionLabel );\n\t\tif ( queryParameter == null ) {\n\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\"Positional parameter \" + positionLabel + \" is not registered with this procedure call\" );\n\t\t}\n\t\treturn queryParameter;\n\t}\n\n\t@Override\n\tpublic <P> ProcedureParameterImplementor<P> resolve(Parameter<P> parameter) {\n\t\tif ( parameters != null\n\t\t\t\t&& parameter instanceof ProcedureParameterImplementor<P> procedureParam ) {\n\t\t\tfor ( var registered : parameters ) {\n\t\t\t\tif ( registered == parameter ) {\n\t\t\t\t\treturn procedureParam;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureParameterMetadataImpl.java#L157-L193","documentation":"The positional counterpart of the named lookup: getQueryParameter(int) calls findQueryParameter(positionLabel), which matches only parameters whose name is null and whose position equals the label. No match means IllegalArgumentException 'Positional parameter N is not registered with this procedure call'. Position labels are 1-based as registered.","triggerScenarios":"call.getParameterBindings().getBinding(2) or StoredProcedureQuery.setParameter(2, value) when position 2 was never registered, or was registered by name (name != null so positional lookup skips it).","commonSituations":"Registering positions 1 and 2 but binding position 3; registering parameters by name and then binding by index; off-by-one errors after adding a new parameter to the procedure; copy-pasting setParameter calls from another procedure with more parameters.","solutions":["Register every positional parameter before binding it: call.registerParameter(2, String.class, ParameterMode.IN)","Check findQueryParameter(position) (or getParameters() on the Jakarta query) before binding optional parameters","Reconcile the positions bound with the positions registered — they must be the same 1-based labels"],"exampleFix":"// before\nq.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN);\nq.setParameter(2, \"note\"); // position 2 never registered\n\n// after\nq.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN);\nq.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);\nq.setParameter(2, \"note\");","handlingStrategy":"validation","validationCode":"// Register every positional parameter before binding\nq.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN);\nq.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);\nq.setParameter(2, \"note\");","typeGuard":null,"tryCatchPattern":"try {\n    call.getParameterBindings().getBinding(2);\n} catch (IllegalArgumentException e) {\n    // position 2 not registered: add the registration or fix the index\n}","preventionTips":["Keep registrations and bindings for positional parameters in one block so indices stay in sync","When adding a procedure parameter, update both the registration list and every binding site","Prefer named parameters for procedures with many optional parameters"],"tags":["hibernate","stored-procedure","parameter-binding"],"backgroundTag":"unregistered-procedure-parameter","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}