dotnet/wpf · error · InvalidOperationException
SR.Format(SR.ValueSerializerContextUnavailable…
Error message
SR.Format(SR.ValueSerializerContextUnavailable, this.GetType().Name )
What it means
CommandValueSerializer.ConvertToString serializes an RoutedCommand as "ns:Class.NameCommand", which requires an ITypeDescriptorContext to look up the ValueSerializer for System.Type. When context is null it cannot resolve the owner type and throws InvalidOperationException (SR.ValueSerializerContextUnavailable).
Solutions
- Provide a valid ITypeDescriptorContext (e.g., obtained from TypeDescriptor context or the WPF XAML designer host) instead of null.
- Outside XAML serialization, format the command directly: $"{command.OwnerType.FullName}.{command.Name}Command".
- Guard the call site: skip serializer-based conversion when no context is available.
Example fix
// before
string s = serializer.ConvertToString(command, null);
// after
string s = command != null
? $"{command.OwnerType.AssemblyQualifiedName}" // or manual ns:Class formatting outside XAML
: string.Empty; Defensive patterns
Strategy: type-guard
Validate before calling
if (context == null)
return $"{command.OwnerType.FullName}.{command.Name}Command"; // manual fallback
return serializer.ConvertToString(command, context); Type guard
bool CanUseValueSerializer(ITypeDescriptorContext ctx) => ctx != null;
Try / catch
try { s = serializer.ConvertToString(command, context); }
catch (InvalidOperationException ex) when (ex.Message.Contains("context"))
{ s = $"{command.OwnerType.FullName}.{command.Name}Command"; } Prevention
- Only call ValueSerializer APIs from within a real XAML/type-descriptor pipeline.
- Never pass null as ITypeDescriptorContext to ConvertToString/ConvertFromString.
- In tests and tools, build a context object or use manual command formatting instead.
When it happens
Trigger: Calling valueSerializer.ConvertToString(routedCommand, null) directly; invoking the serializer outside a XAML/type-descriptor pipeline that normally supplies the context.
Common situations: Custom serialization or designer tooling calling ValueSerializer APIs manually without building an ITypeDescriptorContext; unit tests passing null for context; logging code that tries to stringify commands via the serializer.
Related errors
- SR.Format(SR.TypeValueSerializerUnavailable…
- Cannot countersign an unsigned package.
- Cannot read Page properties because it is not in a tree…
- Cannot sign read-only file.
- Exception of type 'System.InvalidOperationException' was…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/daf46a65ff192b58.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Input/Command/CommandValueSerializer.cs:75
public override string ConvertToString(object value, IValueSerializerContext context)
{
if (value != null)
{
RoutedCommand command = value as RoutedCommand;
if (null != command && null != command.OwnerType)
{
// Known Commands, so write shorter version
if (CommandConverter.IsKnownType(command.OwnerType))
{
return command.Name;
}
else
{
ValueSerializer typeSerializer = null;
if (context == null)
{
throw new InvalidOperationException(SR.Format(SR.ValueSerializerContextUnavailable, this.GetType().Name ));
}
// Get the ValueSerializer for the System.Type type
typeSerializer = context.GetValueSerializerFor(typeof(Type));
if (typeSerializer == null)
{
throw new InvalidOperationException(SR.Format(SR.TypeValueSerializerUnavailable, this.GetType().Name ));
}
return $"{typeSerializer.ConvertToString(command.OwnerType, context)}.{command.Name}Command";
}
}
}
else
return string.Empty;
throw GetConvertToException(value, typeof(string));
}View on GitHub (pinned to 81131a70a4)