{"record":{"id":"677c0651ebd70e7a","repo":"dotnet/efcore","slug":"the-rows-affected-parameter-cannot-be-added-to-the","errorCode":null,"errorMessage":"The rows affected parameter cannot be added to the stored procedure '{sproc}' because the rows affected are already returned via another parameter, via the stored procedure return value or via a result column.","messagePattern":"The rows affected parameter cannot be added to the stored procedure '(.+?)' because the rows affected are already returned via another parameter, via the stored procedure return value or via a result column\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs","lineNumber":577,"sourceCode":"    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    public virtual StoredProcedureParameter? FindRowsAffectedParameter()\n        => _rowsAffectedParameter;\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    public virtual StoredProcedureParameter AddRowsAffectedParameter()\n    {\n        if (_rowsAffectedParameter != null\n            || _rowsAffectedResultColumn != null\n            || _isRowsAffectedReturned)\n        {\n            throw new InvalidOperationException(\n                RelationalStrings.StoredProcedureDuplicateRowsAffectedParameter(\n                    ((IReadOnlyStoredProcedure)this).GetStoreIdentifier()?.DisplayName()));\n        }\n\n        var parameter = new StoredProcedureParameter(this, rowsAffected: true, propertyName: null, originalValue: null);\n        _parameters.Add(parameter);\n        _rowsAffectedParameter = parameter;\n\n        return parameter;\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    public virtual IReadOnlyList<StoredProcedureResultColumn> ResultColumns","sourceCodeStart":559,"sourceCodeEnd":595,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs#L559-L595","documentation":"Thrown by StoredProcedure.AddRowsAffectedParameter when any rows-affected capture already exists — either a rows-affected parameter (_rowsAffectedParameter), a rows-affected result column, or the IsRowsAffectedReturned flag is set. EF permits exactly one rows-affected channel per stored procedure.","triggerScenarios":"StoredProcedure.cs:573-580: _rowsAffectedParameter != null || _rowsAffectedResultColumn != null || _isRowsAffectedReturned. Produced by calling AddRowsAffectedParameter() after ReturnsRowsAffected() or AddRowsAffectedResultColumn().","commonSituations":"Stacking .ReturnsRowsAffected() and .RowsAffectedParameter(); scaffolding a sproc that returns rows affected and then adding a parameter manually; copying config blocks across insert/update sprocs.","solutions":["Choose one rows-affected mechanism and remove the others before adding the parameter.","Reset IsRowsAffectedReturned (reconfigure the sproc) if you intend to use a parameter instead of the return value.","Audit the sproc builder calls so only one of parameter / result column / return value is used."],"exampleFix":"// before\nvar s = eb.UpdateStoredProcedure();\ns.ReturnsRowsAffected();\ns.AddRowsAffectedParameter(); // throws\n\n// after\nvar s = eb.UpdateStoredProcedure();\ns.AddRowsAffectedParameter();","handlingStrategy":"validation","validationCode":"static StoredProcedureParameter AddRowsAffectedParamOnce(StoredProcedure sproc)\n{\n    if (sproc.FindRowsAffectedParameter() is not null\n        || sproc.FindRowsAffectedResultColumn() is not null\n        || sproc.IsRowsAffectedReturned)\n    {\n        throw new InvalidOperationException(\"Rows affected already captured on this sproc.\");\n    }\n    return sproc.AddRowsAffectedParameter();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pick one rows-affected channel per sproc and document it.","Avoid scaffolding-then-reconfiguring without clearing prior config."],"tags":["relational","stored-procedure","rows-affected","duplicate"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}