{"record":{"id":"745273afc6cda22a","repo":"dotnet/wpf","slug":"sr-expandpositionalparameterswithreadonlyproperties","errorCode":null,"errorMessage":"SR.ExpandPositionalParametersWithReadOnlyProperties","messagePattern":"SR\\.ExpandPositionalParametersWithReadOnlyProperties","errorType":"exception","errorClass":"XamlXmlWriterException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlXmlWriter.cs","lineNumber":1951,"sourceCode":"                        if ((potentialProperty.Type.UnderlyingType == paraminfo.ParameterType) &&\n                            (XamlObjectReader.GetConstructorArgument(potentialProperty) == paraminfo.Name))\n                        {\n                            matchingProperty = potentialProperty;\n                            break;\n                        }\n                    }\n\n                    if (matchingProperty is null)\n                    {\n                        throw new XamlXmlWriterException(SR.ConstructorNotFoundForGivenPositionalParameters);\n                    }\n\n                    XamlMember member = objectXamlType.GetMember(matchingProperty.Name);\n                    Debug.Assert(member is not null);\n\n                    if (member.IsReadOnly)\n                    {\n                        throw new XamlXmlWriterException(SR.ExpandPositionalParametersWithReadOnlyProperties);\n                    }\n\n                    writer.ppStateInfo.NodesList[i].Insert(0, new XamlNode(XamlNodeType.StartMember, member));\n                    writer.ppStateInfo.NodesList[i].Add(new XamlNode(XamlNodeType.EndMember));\n                }\n            }\n\n            private ParameterInfo[] GetParametersInfo(XamlType objectXamlType, int numOfParameters)\n            {\n                IList<XamlType> paramXamlTypes = objectXamlType.GetPositionalParameters(numOfParameters);\n\n                if (paramXamlTypes is null)\n                {\n                    throw new XamlXmlWriterException(SR.ConstructorNotFoundForGivenPositionalParameters);\n                }\n\n                Type[] paramClrTypes = new Type[numOfParameters];\n","sourceCodeStart":1933,"sourceCodeEnd":1969,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlXmlWriter.cs#L1933-L1969","documentation":"After matching a constructor parameter to a [ConstructorArgument] property, the writer checks that the property is writable; expansion works by inserting StartMember/EndMember assignment nodes, which requires a settable property. A read-only matched property triggers XamlXmlWriterException ExpandPositionalParametersWithReadOnlyProperties.","triggerScenarios":"Expanding positional parameters where a matched [ConstructorArgument] property has IsReadOnly == true (get-only property, indexer, or read-only collection property).","commonSituations":"Immutable-style markup extensions exposing get-only properties with [ConstructorArgument], porting types that changed from settable to read-only properties, source-generated properties without setters.","solutions":["Add a setter (internal or private is not enough — make it settable) to the [ConstructorArgument] property.","Remove [ConstructorArgument] from read-only properties and use a constructor overload the writer can expand.","Re-expose the value via a settable backing property used only for XAML.","Catch XamlXmlWriterException and write explicit member nodes with a different serialization strategy."],"exampleFix":"// before\n[ConstructorArgument(\"key\")] public string Key { get; }\n// after\n[ConstructorArgument(\"key\")] public string Key { get; set; }","handlingStrategy":"type-guard","validationCode":"foreach (var prop in caaProps) if (prop.IsReadOnly) throw new InvalidOperationException($\"[ConstructorArgument] property {prop.Name} must be settable\");","typeGuard":"bool IsSettableCaaProp(PropertyInfo p) => p.GetSetMethod(nonPublic: false) is not null && p.GetCustomAttribute<ConstructorArgumentAttribute>() is not null;","tryCatchPattern":"try { writer.WriteEndObject(); } catch (XamlXmlWriterException ex) when (ex.Message.Contains(\"ReadOnly\")) { /* serialize with explicit members instead */ }","preventionTips":["Give all [ConstructorArgument] properties public setters.","Do not mark ConstructorArgument properties as get-only in immutable designs.","Round-trip test markup extensions in CI."],"tags":["xaml","positional-parameters","read-only-property"],"backgroundTag":"unsupported-operation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}