{"record":{"id":"374a2daf61069bfd","repo":"dotnet/efcore","slug":"no-property-named-property-found-on-the-entity-374a2d","errorCode":null,"errorMessage":"No property named '{property}' found on the entity type '{entityType}' corresponding to the parameter on the stored procedure '{sproc}'.","messagePattern":"No property named '(.+?)' found on the entity type '(.+?)' corresponding to the parameter on the stored procedure '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":709,"sourceCode":"                            entityType.DisplayName(), resultColumn.PropertyName, storeObjectIdentifier.DisplayName()));\n                default:\n                    Check.DebugFail(\"Unexpected stored procedure type: \" + storeObjectIdentifier.StoreObjectType);\n                    break;\n            }\n        }\n\n        var originalValueProperties = new Dictionary<string, IProperty>(properties);\n        var parameterNames = new HashSet<string>();\n        foreach (var parameter in sproc.Parameters)\n        {\n            IProperty? property = null;\n            if (parameter.PropertyName != null)\n            {\n                if (parameter.ForOriginalValue == true)\n                {\n                    if (!originalValueProperties.TryGetAndRemove(parameter.PropertyName, out property))\n                    {\n                        throw new InvalidOperationException(\n                            RelationalStrings.StoredProcedureParameterNotFound(\n                                parameter.PropertyName, entityType.DisplayName(), storeObjectIdentifier.DisplayName()));\n                    }\n\n                    if (storeObjectIdentifier.StoreObjectType == StoreObjectType.InsertStoredProcedure)\n                    {\n                        throw new InvalidOperationException(\n                            RelationalStrings.StoredProcedureOriginalValueParameterOnInsert(\n                                parameter.Name, storeObjectIdentifier.DisplayName()));\n                    }\n                }\n                else\n                {\n                    if (!properties.TryGetAndRemove(parameter.PropertyName, out property))\n                    {\n                        throw new InvalidOperationException(\n                            RelationalStrings.StoredProcedureParameterNotFound(\n                                parameter.PropertyName, entityType.DisplayName(), storeObjectIdentifier.DisplayName()));","sourceCodeStart":691,"sourceCodeEnd":727,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L691-L727","documentation":"Thrown in the parameter loop of ValidateSproc for an original-value parameter (parameter.ForOriginalValue == true) whose PropertyName is not present in the originalValueProperties dictionary (RelationalModelValidator.cs:705-712). The dictionary is a copy of the entity's properties; when TryGetAndRemove fails the binding references a property the entity does not have.","triggerScenarios":"Calling .HasOriginalValueParameter(x => x.Missing) or .HasOriginalValueParameter(\"RenamedAway\") on a sproc after the property was removed/renamed. Also when the property exists only on a sibling type and the mapping strategy (TPH/TPT/Tpc) didn't include it.","commonSituations":"Renaming a concurrency-token property (e.g., RowVersion) and forgetting to update the original-value parameter binding; scaffolding against stale DB metadata; refactoring a base type that previously declared the property.","solutions":["Point the original-value parameter at an existing property: sp.HasOriginalValueParameter(x => x.CurrentProperty).","If the property was renamed, update the binding to the new name (and consider .HasColumnName to keep the store column name stable).","If the property no longer exists, remove the HasOriginalValueParameter call.","Verify the mapping strategy includes the property (TPT requires base-type PK properties to be added explicitly — see lines 601-631)."],"exampleFix":"// before\nsp.HasOriginalValueParameter(\"RowVersion\"); // property renamed to VersionTag\n\n// after\nsp.HasOriginalValueParameter(x => x.VersionTag).HasName(\"RowVersion\");","handlingStrategy":"validation","validationCode":"foreach (var et in modelBuilder.Model.GetEntityTypes())\n{\n    var propNames = et.GetProperties().Select(p => p.Name).ToHashSet();\n    foreach (var sproc in new[] { et.GetInsertStoredProcedure(), et.GetUpdateStoredProcedure(), et.GetDeleteStoredProcedure() })\n    {\n        if (sproc is null) continue;\n        foreach (var p in sproc.Parameters.Where(p => p.ForOriginalValue == true && p.PropertyName is not null))\n            if (!propNames.Contains(p.PropertyName))\n                throw new InvalidOperationException($\"Original-value parameter '{p.PropertyName}' on sproc '{sproc.GetStoreIdentifier().DisplayName}' is not a property of '{et.Name}'.\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try { _ = ctx.Model; }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"corresponding to the parameter\"))\n{\n    logger.LogError(\"Original-value parameter references a missing property. {Msg}\", ex.Message);\n    throw;\n}","preventionTips":["Use lambda-based HasOriginalValueParameter(x => x.Prop) so renames are compile errors.","Re-run model validation after property renames or mapping-strategy changes.","Keep concurrency-token property names stable; use HasName to alias the store parameter."],"tags":["efcore","relational","stored-procedure","parameter","original-value","property-mapping","model-validation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}