stride3d/stride · error · NotSupportedException

ConvertBack is not supported by this IValueConverter.

Error message

ConvertBack is not supported by this IValueConverter.

What it means

LocalizableConverter (base class of the localization value converters in Stride.Core.Translation.Presentation) is one-way by design: it converts raw localized values for display. Its virtual ConvertBack default implementation throws NotSupportedException because reverse-translating a displayed string to its source value has no general solution.

Solutions

  1. Set binding Mode=OneWay explicitly; two-way localization bindings are unsupported.
  2. Override ConvertBack in your own derived converter to return the raw value if your data model stores the same string that is displayed.
  3. Restructure so the ViewModel owns the translatable key and the localized text is presentation-only.

Example fix

// before
BindingOperations.SetBinding(tb, TextBlock.TextProperty, new Binding("Name") { Converter = new TranslateConverter(), Mode = BindingMode.TwoWay });
// after
BindingOperations.SetBinding(tb, TextBlock.TextProperty, new Binding("Name") { Converter = new TranslateConverter(), Mode = BindingMode.OneWay });
Defensive patterns

Strategy: validation

Validate before calling

var binding = new Binding("Name") { Converter = new TranslateConverter(), Mode = BindingMode.OneWay };

Try / catch

try { /* binding setup */ }
catch (NotSupportedException) when (ex.Message.Contains("ConvertBack")) { /* switch binding to OneWay or override ConvertBack */ }

Prevention

When it happens

Trigger: Any binding using a LocalizableConverter-derived converter (e.g. TranslateConverter/PluralizationConverter) with TwoWay or OneWayToSource mode, so the binding engine calls ConvertBack.

Common situations: Making a localized label editable; switching binding modes while refactoring; assuming the converter behaves like standard framework converters that support round-trips.

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


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/e167e05d861a5d4c. Report an issue: GitHub.

Appendix: source

Thrown at sources/presentation/Stride.Core.Translation.Presentation/ValueConverters/LocalizableConverter.cs:35

    public abstract class LocalizableConverter<TConverter> : MarkupExtension, IValueConverter
        where TConverter : LocalizableConverter<TConverter>, new()
    {
        // Keep a cache per assembly (since localization is grouped per assembly)
        private static readonly Dictionary<Assembly, LocalizableConverter<TConverter>> Cache = new Dictionary<Assembly, LocalizableConverter<TConverter>>();

        /// <summary>
        /// The assembly to lookup the translation.
        /// </summary>
        protected Assembly Assembly { get; private set; }

        /// <inheritdoc />
        public abstract object Convert(object value, Type targetType, object parameter, CultureInfo culture);

        /// <inheritdoc />
        public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // By default, a localizable converter is one-way only.
            throw new NotSupportedException($"ConvertBack is not supported by this {nameof(IValueConverter)}.");
        }

        /// <inheritdoc/>
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            var assembly = MarkupExtensionHelper.RetrieveLocalAssembly(serviceProvider);
            if (!Cache.TryGetValue(assembly, out var converter))
            {
                converter = new TConverter { Assembly = assembly };
                Cache.Add(assembly, converter);
            }
            return converter;
        }
    }
}

View on GitHub (pinned to 96fad776d2)