JetBrains/intellij-community · error · ContractConversionException
changeSignature.contract.converter.parameter.removed
changeSignature.contract.converter.parameter.removed
Error message
Parameter '{0}' was deleted, but contract clause '{1}' depends on it What it means
Thrown by the private convertContract in ContractConverter when a parameter that a contract clause constrains (constraint != ANY_VALUE, i.e. not '_') is removed by the Change Signature operation (oldToNewIndex[i] == -1). Dropping the parameter would silently invalidate the clause's meaning, so the refactoring refuses to proceed.
Source
Thrown at java/java-impl/src/com/intellij/refactoring/changeSignature/ContractConverter.java:79
result.add(convertContract(contract, newToOldIndex, oldToNewIndex, oldParameterNames));
}
if (result.equals(contracts)) return annotation;
return JavaMethodContractUtil.updateContract(annotation, result);
}
private static @NotNull StandardMethodContract convertContract(@NotNull StandardMethodContract contract,
int @NotNull [] newToOldIndex,
int @NotNull [] oldToNewIndex,
String @NotNull [] oldParameterNames) throws ContractConversionException {
if (contract.getParameterCount() != oldToNewIndex.length) {
// invalid contract
throw new ContractConversionException(JavaRefactoringBundle.message("changeSignature.contract.converter.invalid.clause", contract));
}
for (int i = 0; i < contract.getParameterCount(); i++) {
if (contract.getParameterConstraint(i) != StandardMethodContract.ValueConstraint.ANY_VALUE && oldToNewIndex[i] == -1) {
String paramRemovedMessage = JavaRefactoringBundle.message("changeSignature.contract.converter.parameter.removed",
oldParameterNames[i], contract);
throw new ContractConversionException(paramRemovedMessage);
}
}
StandardMethodContract.ValueConstraint[] newConstraints = IntStreamEx.of(newToOldIndex)
.mapToObj(idx -> idx == -1 ? StandardMethodContract.ValueConstraint.ANY_VALUE : contract.getParameterConstraint(idx))
.toArray(StandardMethodContract.ValueConstraint.class);
ContractReturnValue returnValue = contract.getReturnValue();
if (returnValue instanceof ContractReturnValue.ParameterReturnValue) {
int oldIndex = ((ContractReturnValue.ParameterReturnValue)returnValue).getParameterNumber();
if (oldIndex >= contract.getParameterCount()) {
String errorRefMessage = JavaRefactoringBundle.message("changeSignature.contract.converter.invalid.return.reference", returnValue);
throw new ContractConversionException(errorRefMessage);
}
int index = oldToNewIndex[oldIndex];
if (index == -1) {
String paramRemovedMessage = JavaRefactoringBundle.message("changeSignature.contract.converter.return.parameter.removed",
oldParameterNames[oldIndex], contract);
throw new ContractConversionException(paramRemovedMessage);
}View on GitHub (pinned to be881553f2)
Solutions
- Instead of deleting the parameter, keep it or replace its constraint with '_' only after you delete the parameter — but the IDE requires the clause not depend on it, so first restructure the logic so the constraint is unnecessary.
- Split the refactoring: first edit @Contract manually to remove dependence on that parameter (change its constraint to '_'), then run Change Signature to delete the parameter.
- Alternatively delete the whole @Contract annotation if it is no longer meaningful after the parameter removal.
Example fix
// before: deleting 's' via Change Signature throws
@Contract("null -> fail")
void f(String s) { ... }
// after: drop the constraint first, then delete the parameter
// step 1: @Contract(" -> fail") void f(String s) -> simplify to no contract, or keep param Defensive patterns
Strategy: validation
Validate before calling
// before deleting parameter i, check no clause constrains it
for (StandardMethodContract c : StandardMethodContract.parseContract(contractText)) {
if (c.getParameterConstraint(i) != StandardMethodContract.ValueConstraint.ANY_VALUE) {
// clause depends on the parameter to be deleted; adjust contract first
}
} Try / catch
try { ContractConverter.convertContract(method, info); } catch (ContractConversionException e) { /* relax the constraint to '_' or drop the annotation, then delete the parameter */ } Prevention
- Before removing a parameter, scan @Contract clauses for non-'_' constraints on it.
- Treat constrained parameters as API surface; they are observable via the contract.
- Prefer changing the constraint to '_' manually in the editor before running Change Signature.
When it happens
Trigger: Change Signature removing a parameter that appears with a real constraint (null, !null, true, false) in some @Contract clause; e.g. deleting parameter 's' from @Contract("null -> fail") boolean f(String s).
Common situations: Cleaning up 'unused' parameters that are actually load-bearing for nullability contracts; API slimming on annotated public methods; batch refactor scripts deleting parameters without checking annotations.
Related errors
- changeSignature.contract.converter.return.parameter.removed
- changeSignature.contract.converter.external.annotations
- changeSignature.contract.converter.inherited.annotation
- changeSignature.contract.converter.mutation.contract
- changeSignature.contract.converter.definition.error
AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14).
Data as JSON: /api/errors/d6ef577743c7b456.
Report an issue: GitHub.