{"record":{"id":"44318e91ba0b65e6","repo":"JetBrains/intellij-community","slug":"changesignature-contract-converter-return-paramete","errorCode":"changeSignature.contract.converter.return.parameter.removed","errorMessage":"Parameter '{0}' was deleted, but contract clause '{1}' returns it","messagePattern":"Parameter '(.+?)' was deleted, but contract clause '(.+?)' returns it","errorType":"exception","errorClass":"ContractConversionException","httpStatus":null,"severity":"error","filePath":"java/java-impl/src/com/intellij/refactoring/changeSignature/ContractConverter.java","lineNumber":96,"sourceCode":"                                                                   oldParameterNames[i], contract);\n        throw new ContractConversionException(paramRemovedMessage);\n      }\n    }\n    StandardMethodContract.ValueConstraint[] newConstraints = IntStreamEx.of(newToOldIndex)\n                                                                         .mapToObj(idx -> idx == -1 ? StandardMethodContract.ValueConstraint.ANY_VALUE : contract.getParameterConstraint(idx))\n                                                                         .toArray(StandardMethodContract.ValueConstraint.class);\n    ContractReturnValue returnValue = contract.getReturnValue();\n    if (returnValue instanceof ContractReturnValue.ParameterReturnValue) {\n      int oldIndex = ((ContractReturnValue.ParameterReturnValue)returnValue).getParameterNumber();\n      if (oldIndex >= contract.getParameterCount()) {\n        String errorRefMessage = JavaRefactoringBundle.message(\"changeSignature.contract.converter.invalid.return.reference\", returnValue);\n        throw new ContractConversionException(errorRefMessage);\n      }\n      int index = oldToNewIndex[oldIndex];\n      if (index == -1) {\n        String paramRemovedMessage = JavaRefactoringBundle.message(\"changeSignature.contract.converter.return.parameter.removed\",\n                                                                   oldParameterNames[oldIndex], contract);\n        throw new ContractConversionException(paramRemovedMessage);\n      }\n      returnValue = ContractReturnValue.returnParameter(index);\n    }\n    return new StandardMethodContract(newConstraints, returnValue);\n  }\n\n  private static int[] reverseIndex(int oldParameterCount, int[] newToOldIndex) {\n    int[] oldToNewIndex = new int[oldParameterCount];\n    Arrays.fill(oldToNewIndex, -1);\n    for (int i = 0; i < newToOldIndex.length; i++) {\n      int oldIndex = newToOldIndex[i];\n      if (oldIndex >= 0 && oldIndex < oldParameterCount) {\n        oldToNewIndex[oldIndex] = i;\n      }\n    }\n    return oldToNewIndex;\n  }\n","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/JetBrains/intellij-community/blob/be881553f2a76ac8b4ea53950d93f0de78295c19/java/java-impl/src/com/intellij/refactoring/changeSignature/ContractConverter.java#L78-L114","documentation":"Thrown by the private convertContract in ContractConverter when a contract clause's return value is a parameter reference (e.g. '-> param1') and Change Signature deletes exactly that parameter (oldToNewIndex[oldIndex] == -1). The clause promises to return an argument the new signature no longer has, so conversion is refused.","triggerScenarios":"Running Change Signature that removes parameter k on a method with @Contract(\"... -> paramK\"); e.g. deleting 'b' from @Contract(\"null, _ -> param2\") Object f(String a, Object b).","commonSituations":"API cleanup deleting a passthrough parameter that the contract returns; wrapper/delegate methods annotated with param-returning contracts; batch parameter removal ignoring annotations.","solutions":["Change the contract's return value first: replace '-> paramK' with a static return ('-> new', '-> null') or delete the annotation, then run Change Signature.","Keep the parameter if the return-the-argument semantics must be preserved.","After manual contract cleanup, rerun the refactoring so remaining clauses convert automatically."],"exampleFix":"// before: deleting 'b' throws\n@Contract(\"null, _ -> param2\")\nObject f(String a, Object b) { return b; }\n// after: adjust contract to the new signature\n@Contract(\"null -> null\")\nObject f(String a) { return null; }","handlingStrategy":"validation","validationCode":"// before deleting parameter k, check the return value does not reference it\nfor (StandardMethodContract c : StandardMethodContract.parseContract(contractText)) {\n  ContractReturnValue rv = c.getReturnValue();\n  if (rv instanceof ContractReturnValue.ParameterReturnValue prv && prv.getParameterNumber() == k) {\n    // clause returns the parameter being deleted; change return value or keep the parameter\n  }\n}","typeGuard":null,"tryCatchPattern":"try { ContractConverter.convertContract(method, info); } catch (ContractConversionException e) { /* if the deleted parameter is returned, change '-> paramK' or drop the annotation first */ }","preventionTips":["Check '-> paramN' return references before deleting any parameter via Change Signature.","For passthrough methods (return an argument), keep the parameter or rewrite the contract return.","Review contracts as part of the checklist for any signature-affecting refactoring."],"tags":["java","refactoring","change-signature","contract-annotation","parameter-removal"],"backgroundTag":null,"analyzedSha":"be881553f2a76ac8b4ea53950d93f0de78295c19","analyzedAt":"2026-08-14T14:13:06.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}