dotnet/wpf · error · InvalidOperationException
SR.AttachedPropertyOnTypeConvertedOrStringProperty
Error message
SR.AttachedPropertyOnTypeConvertedOrStringProperty
What it means
When XamlObjectReader converts a property value to a string (via a type converter) it checks whether that value itself exposes attached-property content (GetAttachedProperties). If it does, the XAML output would lose those attached properties, which is unrepresentable in attribute/string form, so an InvalidOperationException names the property, value, and the offending attached property.
Solutions
- Remove attached-property setters from values that are serialized through a type converter or as strings, or move them to a container element in XAML.
- Change the property's serialization so the value is written as an object element (remove/replace the TypeConverter) so attached properties can be emitted as child elements.
- Set the attached properties in the XAML on the parent/other element rather than on the converted value.
Example fix
// before canvas.Children.Add(text); // text has Canvas.Left set and is stored via TypeConverter string property xamlText = tc.ConvertToString(text); // throws: attached properties lost // after // serialize text as an object element instead of a converted string Canvas.SetLeft(text, 10); // move attached property usage to the element tree, not a string property
Defensive patterns
Strategy: validation
Validate before calling
static void EnsureNoAttachedProps(object value) {
if (value is DependencyObject d) {
foreach (var p in new[]{Canvas.LeftProperty, Canvas.TopProperty, Grid.RowProperty})
if (d.ReadLocalValue(p) != DependencyProperty.UnsetValue)
throw new InvalidOperationException("Attached properties set on a type-converted/string property value.");
}
} Try / catch
try { xaml = reader.ReadSubtree(); /* serialize */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("attached")) { /* move attached properties or change serialization mode */ } Prevention
- Do not set attached properties on values that are serialized through TypeConverters.
- Prefer serializing such values as object elements, not strings.
- Audit custom TypeConverters for complex object inputs.
When it happens
Trigger: Reading an object where property P's value is type-converted or written as a string, and that value has attached properties set (e.g. a string/converted value carrying Canvas.Left, Grid.Row, etc.) — ThrowIfPropertiesAreAttached with property != null (XamlObjectReader.cs:906-908).
Common situations: A custom TypeConverter that converts a complex object (with attached properties set on it) to a string; WPF types stored in a property with a converter attached while layout attached properties were applied to them; cloning objects between UI trees during serialization.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- SR.AttachedPropertyOnDictionaryKey
- SR.Format(SR.InvalidStringVirtualizationCacheLength, s)
- SR.ObjectReaderAttachedPropertyNotFound
- SR.ParserAbandonedTypeConverterText
- SR.ParserTypeConverterTextNeedsEndElement
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/8eadc916bb4a1e5f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlObjectReader.cs:908
}
else
{
context.Instance = null;
valueInfo = ObjectMarkupInfo.ForObject(propertyValue, context, propertyConverter);
}
}
return valueInfo;
}
private static void ThrowIfPropertiesAreAttached(object value, XamlMember property, SerializerContext context)
{
var props = context.Runtime.GetAttachedProperties(value);
if (props is not null)
{
if (property is not null)
{
throw new InvalidOperationException(SR.Format(SR.AttachedPropertyOnTypeConvertedOrStringProperty, property.Name, value.ToString(), props[0].Key.ToString()));
}
else
{
throw new InvalidOperationException(SR.Format(SR.AttachedPropertyOnDictionaryKey, value.ToString(), props[0].Key.ToString()));
}
}
}
// Reproduce the logic of System.ComponentModel.ReflectPropertyDescriptor.ShouldSerializeValue
private static bool ShouldWriteProperty(object source, XamlMember property, SerializerContext context)
{
bool isReadOnly = !context.IsPropertyWriteVisible(property);
if (!isReadOnly)
{
object defaultValue;
if (GetDefaultValue(property, out defaultValue))
{View on GitHub (pinned to 81131a70a4)