stride3d/stride · error · InvalidOperationException

Converter is null but following Converter is not null

Error message

Converter{i} is null but following Converter{i + 1} is not null

What it means

Chained.ConvertBack throws this InvalidOperationException when a converter is null after the back-conversion has already started, meaning a null appears in the middle of the chain while later converters still exist. Back-conversion can skip leading nulls but not gaps.

Solutions

  1. Ensure no null converter appears before a non-null one in the chain
  2. Set the binding to OneWay when the chain does not support ConvertBack
  3. Fix converter ordering so leading entries are non-null

Example fix

// before
converter0 = null; converter1 = new TrimConverter(); // gap hit in ConvertBack
// after
converter0 = new TrimConverter(); converter1 = new TrimConverter();
Defensive patterns

Strategy: validation

Validate before calling

if (converters.Any(c => c == null) && converters.TakeWhile(c => c != null).Count() < Array.FindLastIndex(converters, c => c != null))
    throw new InvalidOperationException("Gap in converter chain for ConvertBack");

Type guard

bool IsValidForConvertBack(IValueConverter[] c) => c.Length == 0 || Array.TrueForAll(c.Take(Array.FindLastIndex(c, x => x != null) + 1).ToArray(), x => x != null);

Try / catch

try { output = chained.ConvertBack(value, targetType, parameter, culture); }
catch (InvalidOperationException ex) { Log.Error("ConvertBack chain gap", ex); return Binding.DoNothing; }

Prevention

When it happens

Trigger: A ChainedConverter whose Converter0 is null but Converter1 is set, hit during ConvertBack after conversion started; runtime mutation leaving a null in the middle of the chain.

Common situations: Two-way bindings (default binding mode) exercising ConvertBack on a chain configured only for forward use; mis-ordered converter declarations in XAML; a converter step disposed and set to null at runtime.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Wpf/ValueConverters/Chained.cs:287

            }
            return output;
        }

        /// <inheritdoc/>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var output = value;

            var conversionStarted = false;

            for (var i = MaxConverterCount - 1; i >= 0; --i)
            {
                var input = output;
                if (converters[i] == null)
                {
                    if (!conversionStarted)
                        continue;
                    throw new InvalidOperationException($"Converter{i} is null but following Converter{i + 1} is not null");
                }

                conversionStarted = true;

                var type = converterTargetType[i] ?? (i == 0 ? targetType : typeof(object));
                output = converters[i].ConvertBack(input, type, converterParameters[i], culture);
            }
            return output;
        }
    }
}

View on GitHub (pinned to 96fad776d2)