dotnet/wpf · error · ArgumentException
SR.Format(SR.NotAmbientProperty…
Error message
SR.Format(SR.NotAmbientProperty, xamlMember.DeclaringType.Name, xamlMember.Name)
What it means
ObjectWriterContext.FindAmbientValues validates that every XamlMember passed in the properties collection has IsAmbient set. When a non-ambient property is supplied it throws ArgumentException with SR.NotAmbientProperty, naming the declaring type and member, with paramName "properties".
Solutions
- Add [Ambient] (System.Xaml.Schema.AmbientAttribute) to the property so IsAmbient returns true, or mark it ambient in your custom schema context.
- Filter the properties list before calling: only include members where xamlMember.IsAmbient is true.
- Ensure you are using the correct SchemaContext instance so ambient metadata is detected as intended.
Example fix
// before
var props = new[] { schemaContext.GetXamlType(typeof(Panel)).GetMember("Children"), xt.GetMember("Tag") }; // Tag is not ambient
// after
var props = new[] { schemaContext.GetXamlType(typeof(Panel)).GetMember("Children") }
.Where(m => m.IsAmbient).ToArray(); Defensive patterns
Strategy: validation
Validate before calling
if (properties.Any(m => !m.IsAmbient))
throw new ArgumentException("All members must be ambient", nameof(properties)); Type guard
static bool AllAmbient(IEnumerable<XamlMember> members) => members.All(m => m.IsAmbient);
Try / catch
try { FindAmbientValues(properties, ceilingTypes, stopAfterFirst); }
catch (ArgumentException ex) when (ex.ParamName == "properties")
{ /* filter out non-ambient members and retry */ } Prevention
- Decorate ambient properties with [Ambient] so IsAmbient is true.
- Filter with .Where(m => m.IsAmbient) before any ambient-lookup API call.
- Do not mix regular members into ambient member lists.
When it happens
Trigger: Calling the API that collects ambient values (e.g. via IAmbientProvider / XamlObjectWriter internals or custom schema context code) and passing a XamlMember in the properties array whose SchemaContext does not mark it ambient.
Common situations: Custom XAML schema contexts or ambient-property lookups where the ambient attribute ([Ambient]) is missing from the property definition; properties enumerated from the wrong type so IsAmbient is false; hand-built XamlMember lists mixing ambient and regular members.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.Format(SR.NotAmbientType, xamlType.Name)
- SR.AbsoluteUriNotAllowed
- SR.CollectionCannotContainNulls
- SR.FrameworkElementFactoryAlreadyParented
- SR.MustBeTriggerAction
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/5b895f56118fd6d8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Context/ObjectWriterContext.cs:317
if (frame.Member == XamlLanguage.Initialization)
{
return frame.XamlType;
}
return frame.Member.Type;
}
private List<AmbientPropertyValue> FindAmbientValues(IEnumerable<XamlType> ceilingTypesEnumerable,
bool searchLiveStackOnly,
IEnumerable<XamlType> types,
XamlMember[] properties,
bool stopAfterFirst)
{
foreach (XamlMember xamlMember in properties)
{
if (!xamlMember.IsAmbient)
{
throw new ArgumentException(SR.Format(SR.NotAmbientProperty, xamlMember.DeclaringType.Name, xamlMember.Name), nameof(properties));
}
}
List<XamlType> ceilingTypes = ceilingTypesEnumerable is not null ? new List<XamlType>(ceilingTypesEnumerable) : null;
List<AmbientPropertyValue> retList = new List<AmbientPropertyValue>();
// Start the search for ambient properties and types starting with the parent frame.
ObjectWriterFrame frame = _stack.PreviousFrame;
ObjectWriterFrame lowerFrame = _stack.CurrentFrame;
while (frame.Depth >= 1)
{
if (searchLiveStackOnly && frame.Depth <= SavedDepth)
{
break;
}
View on GitHub (pinned to 81131a70a4)