{"record":{"id":"2ea139827f99504c","repo":"dotnet/wpf","slug":"sr-convertermustderivefrombase","errorCode":null,"errorMessage":"SR.ConverterMustDeriveFromBase","messagePattern":"SR\\.ConverterMustDeriveFromBase","errorType":"exception","errorClass":"XamlSchemaException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Schema/XamlValueConverter.cs","lineNumber":81,"sourceCode":"                    _isPublic = (ConverterType is null || ConverterType.IsVisible) ? ThreeValuedBool.True : ThreeValuedBool.False;\n                }\n\n                return _isPublic == ThreeValuedBool.True;\n            }\n        }\n\n        protected virtual TConverterBase CreateInstance()\n        {\n            if (ConverterType == typeof(EnumConverter) &&\n                TargetType.UnderlyingType is not null && TargetType.UnderlyingType.IsEnum)\n            {\n                return (TConverterBase)(object)new EnumConverter(TargetType.UnderlyingType);\n            }\n            else if (ConverterType is not null)\n            {\n                if (!typeof(TConverterBase).IsAssignableFrom(ConverterType))\n                {\n                    throw new XamlSchemaException(SR.Format(SR.ConverterMustDeriveFromBase,\n                       ConverterType, typeof(TConverterBase)));\n                }\n\n                return (TConverterBase)Activator.CreateInstance(ConverterType, null);\n            }\n\n            return null;\n        }\n\n        private string GetDefaultName()\n        {\n            if (ConverterType is not null)\n            {\n                if (TargetType is not null)\n                {\n                    return $\"{ConverterType.Name}({TargetType.Name})\";\n                }\n","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Schema/XamlValueConverter.cs#L63-L99","documentation":"XamlValueConverter<TConverterBase>.CreateInstance throws XamlSchemaException('ConverterMustDeriveFromBase') when the configured ConverterType does not derive from (implement/inherit) TConverterBase. The generic converter lazily instantiates ConverterType and must cast it to TConverterBase; validating assignability up front produces a clear schema exception instead of an opaque InvalidCastException later.","triggerScenarios":"Accessing the ConverterInstance property of a XamlValueConverter<TConverterBase> whose ConverterType was set to a class not assignable to TConverterBase — e.g. registering a TypeConverter that does not derive from the expected base (like a ValueSerializer pointing at a TypeConverter, or a generic parameter mismatch when constructing the converter).","commonSituations":"XAML schema/type-converter registrations where the ConverterType string in configuration resolves to the wrong class; swapping a base-converter generic parameter after a refactor; assembly-version changes where a converter class no longer inherits the expected base.","solutions":["Make ConverterType derive from/implement TConverterBase (correct the class or the registration).","Fix the registration so the right base generic is used, e.g. XamlValueConverter<TypeConverter> for TypeConverter-derived classes.","Pre-check typeof(TConverterBase).IsAssignableFrom(converterType) before creating the XamlValueConverter.","Catch XamlSchemaException around ConverterInstance access and fall back to a default converter."],"exampleFix":"// before\nvar c = new XamlValueConverter<ValueSerializer>(typeof(MyTypeConverter), targetType, null); // wrong base\nc.ConverterInstance; // throws\n// after\nvar c = new XamlValueConverter<TypeConverter>(typeof(MyTypeConverter), targetType, null);","handlingStrategy":"validation","validationCode":"if (converterType is not null && !typeof(TConverterBase).IsAssignableFrom(converterType)) throw new InvalidOperationException($\"{converterType} must derive from {typeof(TConverterBase)}\");","typeGuard":"static bool IsValidConverter(Type t) => t is not null && typeof(TConverterBase).IsAssignableFrom(t);","tryCatchPattern":"try { var inst = converter.ConverterInstance; } catch (XamlSchemaException ex) { /* converter does not derive from base */ }","preventionTips":["Match the generic parameter to the converter's actual base (TypeConverter vs ValueSerializer).","Validate registrations with IsAssignableFrom at startup.","Avoid constructing converters from raw type-name strings without verification.","Pin converter assemblies so inheritance chains do not silently change across versions."],"tags":["xaml","schema-exception","type-mismatch","converter"],"backgroundTag":"type-mismatch","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"}