dotnet/efcore · error · InvalidOperationException
The stored procedure
Error message
The stored procedure '{sproc}' cannot be configured to return the rows affected because a rows affected parameter or a rows affected result column for this stored procedure already exists. What it means
Thrown when SetIsRowsAffectedReturned(true) is called on a stored procedure mapping that already has a rows-affected parameter or a rows-affected result column configured. EF exposes exactly one channel for rows-affected, so requesting the return variant on top of an existing one is ambiguous.
Solutions
- Remove the existing rows-affected parameter/result column before enabling IsRowsAffectedReturned.
- Choose a single rows-affected mechanism (parameter, result column, or return value) and configure only that one.
- Clear the stored procedure mapping and rebuild it with the desired rows-affected channel.
Example fix
// before
updateSproc.RowsAffectedParameter("rc");
updateSproc.IsRowsAffectedReturned = true; // throws
// after: pick one mechanism
updateSproc.IsRowsAffectedReturned = true;
// (do not also add a rows-affected parameter) Defensive patterns
Strategy: validation
Validate before calling
// Before enabling IsRowsAffectedReturned, ensure no parameter or result column exists.
if (sproc.RowsAffectedParameter is null && sproc.RowsAffectedResultColumn is null)
sproc.IsRowsAffectedReturned = true;
else
throw new InvalidOperationException(
"Cannot enable rows-affected return: a rows-affected parameter or result column already exists."); Prevention
- Choose exactly one rows-affected channel (parameter, result column, or return value) per stored procedure mapping.
- Configure rows-affected once, declaratively, and avoid mixing fluent calls.
- Add a unit test that asserts the mapping has at most one rows-affected channel.
When it happens
Trigger: StoredProcedure.SetIsRowsAffectedReturned(true) when _rowsAffectedParameter != null || _rowsAffectedResultColumn != null. Happens after calling RowsAffectedParameter(...), RowsAffectedResultColumn(...), and then trying to enable IsRowsAffectedReturned.
Common situations: Switching a stored procedure mapping from a rows-affected parameter to a return-value approach without first removing the parameter; building the mapping programmatically and adding multiple rows-affected channels; copy/paste of configuration calls.
Related errors
- ' ' cannot be configured for the parameter ' ' of the…
- The object ' ' has been removed from the model.
- The original value parameter for the property
- The parameter for the property
- The rows affected parameter cannot be added to the stored…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/9a6f02917e3b3306.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs:446
public virtual bool IsRowsAffectedReturned
{
get => _isRowsAffectedReturned;
set => SetIsRowsAffectedReturned(value);
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual bool SetIsRowsAffectedReturned(bool rowsAffectedReturned)
{
EnsureMutable();
if (_rowsAffectedParameter != null || _rowsAffectedResultColumn != null)
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureRowsAffectedReturnConflictingParameter(
((IReadOnlyStoredProcedure)this).GetStoreIdentifier()?.DisplayName()));
}
_isRowsAffectedReturned = rowsAffectedReturned;
return rowsAffectedReturned;
}
private static void UpdateOverrides(
StoreObjectIdentifier oldId,
StoreObjectIdentifier? newId,
IConventionEntityType entityType)
{
if (oldId == newId)
{
return;
}View on GitHub (pinned to 3a2006ef56)